zoukankan      html  css  js  c++  java
  • 基于Redis实现消息队列的几种方式

    消息队列,常用于解决并发系统中的资源一致性问题,提升峰值的处理能力,同时保证消息的顺序性、可恢复性、必送达性,对应用进行解耦,或者实现异步通讯等。市面上有很多成熟的消息中间件。实际上,基于Redis也可以实现一些简单的消息队列功能,比较典型的方案有:

    • 基于List的 LPUSH+BRPOP 的实现
    • 订阅/发布(Pub/Sub)
    • 基于Sorted-Set的实现
    • 基于Stream类型的实现

    一、基于List的 LPUSH+BRPOP的实现

    典型的命令为:

    LPUSH,将消息入队列 (生产者)
    BRPOP,从队列取出消息,阻塞模式 (消费者)

    该模式的优点:

    • 实现简单
    • Reids支持持久化消息,意味着消息不会丢失,可以重复查看(注意不是消费,只看不用,LRANGE类的指令)。
    • 可以保证顺序,保证使用LPUSH命令,可以保证消息的顺序性
    • 使用RPUSH,可以将消息放在队列的开头,达到优先消息的目的,可以实现简易的消息优先队列。

    该模式的缺点:

    • 做消费确认ACK比较麻烦,就是不能保证消费者在读取之后,未处理后的宕机问题。导致消息意外丢失。通常需要自己维护一个Pending列表,保证消息的处理确认。
    • 不能做广播模式,例如典型的Pub/Discribe模式。
    • 不能重复消费,一旦消费就会被删除
    • 不支持分组消费,需要自己在业务逻辑层解决

    技术没有好坏,只有适合不适合。实际上,在我们之前的项目中也确实用到了该方案。

    二、PUB/SUB,订阅/发布模式

    官方:Publish/Subscribe       Pub/Sub  

    PUBLISH,向信道发送消息
    SUBSCRIBE,用于订阅信道
    UNSUBSCRIBE,取消订阅

    生产者和消费者通过相同的一个信道(Channel)进行交互。信道其实也就是队列。通常会有多个消费者。多个消费者订阅同一个信道,当生产者向信道发布消息时,该信道会立即将消息逐一发布给每个消费者。可见,该信道对于消费者是发散的信道,每个消费者都可以得到相同的消息。典型的对多的关系。

    优点是:

    • 典型的广播模式,一个消息可以发布到多个消费者
    • 多信道订阅,消费者可以同时订阅多个信道,从而接收多类消息
    • 消息即时发送,消息不用等待消费者读取,消费者会自动接收到信道发布的消息

    缺点是:

    • 消息一旦发布,不能接收。换句话就是发布时若客户端不在线,则消息丢失,不能寻回
    • 不能保证每个消费者接收的时间是一致的
    • 若消费者客户端出现消息积压,到一定程度,会被强制断开,导致消息意外丢失。通常发生在消息的生产远大于消费速度时

    可见,Pub/Sub 模式不适合做消息存储,消息积压类的业务,而是擅长处理广播,即时通讯,即时反馈的业务。

    实现:

    Jedis提供了JedisPubSub抽象类,我们只要继承该类,实现其中的onMessage,onSubscribe,onUnsubscribe等方法即可。

    三、基于SortedSet有序集合的实现

    ZADD KEY score member,压入集合
    ZRANGEBYSCORE,依据score获取成员

    有序集合的方案是在自己确定消息顺ID时比较常用,使用集合成员的Score来作为消息ID,保证顺序,还可以保证消息ID的单调递增。通常可以使用时间戳+序号的方案。确保了消息ID的单调递增,利用SortedSet的依据Score排序的特征,就可以制作一个有序的消息队列了。

    和上面的方案相比,优点就是可以自定义消息ID,在消息ID有意义时,比较重要。缺点也明显,不允许重复消息(以为是集合),同时消息ID确定有错误会导致消息的顺序出错。

    所以,若不是需要自定义消息ID,这个方案好像有点鸡肋...

    四、基于 Stream 类型的实现

    官网:Introduction to Redis Streams

    Stream是redis 5.0推出的新类型,专门用来实现消息队列的。支持自动生成消息ID,分组消费,ACK,消息转移,队列监控等核心消息队列功能。

    不积跬步,无以至千里。不积小流,无以成江海!
  • 相关阅读:
    第四周作业
    jsp第二次作业
    jsp第一次作业
    软件测试1
    activity
    listview
    sql
    登录
    第二次安卓作业
    安卓第一周作业
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/10220230.html
Copyright © 2011-2022 走看看