Broker: 做事器,作为Server供应核心做事,一样平常会包含多个Q。Producer: 生产者,业务的发起方,卖力生产传输给broker,Consumer: 消费者,业务的处理方,卖力从broker获取消息并进行业务逻辑处理2.2 它办理了我们哪些问题
1、解耦: 比如说系统A会交给系统B去处理一些事情,但是A不想直接跟B有关联,避免耦合太强,就可以通过在A,B中间加入行列步队,A将要任务的事情交给行列步队 ,B订阅行列步队来实行任务。
这种场景很常见,比如A是订单系统,B是库存系统,可以通过行列步队把减少库存的事情交予B系统去处理。如果A系统同时想让B、C、D…多个别系处理问题的时候,这种上风就更加明显了。
2、有序性: 前辈先出事理,先来先处理,比如一个别系处理某件事须要很长一段韶光,但是在处理这件事情时候,有其他人也发出了要求,可以把要求放在队里,一个一个来处理。

对数据的顺序性和同等性有强需求的业务,比如同一张银行卡同时被多个入口利用,须要担保入账出账的顺序性,避免涌现数据不一致。
3、路由: 按照不同的规则,将行列步队中发送到不同的其他行列步队中
通过行列步队将不同染色的要求发送到不同的做事去操作。这样达成了流量按照业务拆分的目的。
4、异步处理: 处理一项任务的时候,有3个步骤A、B、C,须要先完成A操作, 然后做B、C 操作。任务实行成功与否强依赖A的结果,但不依赖B、C 的结果。如果我们利用串行的实行办法,那边那里理任务的周期就会变长,系统的整体吞吐能力也会降落(在同一个别系中做异步实在也是比较大的开销),以是利用行列步队是比较好的办法。
登录操作便是范例的场景:A:实行登录并得到结果、B:记录登录日志、C:将用户信息和Token写入缓存。 实行完A就可以从登录页跳到首页了,B、C让做事逐步去消化,不壅塞当前操作。
5、削峰: 将峰值期间的操作减少,比如A同学的全体操作流程包含12个步骤,后续的11个步骤是不须要强关注结果的数据,可以放在行列步队中。
详细可参考笔者这篇《MQ系列1:中间件实行事理》。
2.3 行列步队知足的业务特性2.3.1 有序性正如上面提到的有序性一样,他能够担保按照生产的顺序进行处理和消费,避免被无序处理的情形发生。
2.3.2 去重同样的,生产和消费的须要担保幂等性事理。避免涌现重复实行的情形,而行列步队的去重机制,也须要确保避免被重复消费的问题。
2.3.3 的可靠性传输行列步队的数据可以实现重试、持久化存储、去世信行列步队记录等,以避免无法成功通报所产生的不一致征象。当做事器或者消费者规复康健的时候,可以连续读取消息进行处理,防止遗漏。
3 利用Redis的List实现行列步队轻微学过数据构造都知道。我们常常说Queue(行列步队),他的存储和利用规则是【前辈先出】,栈的存储和利用规则是【前辈后出】。以是List实质上是一个线性的有序构造,也便是Queue的存储关系,它能够担保消费的有序性,按照顺序进行处理。
3.1 入列操作 LPUSH即进行生产,入列操作语法:
LPUSH key element[element...]
如果key存在,Producer 通过 LPUSH 将插入该行列步队的头部;如果 key 不存在,则是先创建一个空行列步队,然后在进行数据插入。下面举个例子,往行列步队中插入几个,然后得到的返回值是插入的个数。
> LPUSH msg_queue msg1 msg2 msg3(integer) 3
这边往 key 为 msg_queue 的行列步队中插入了三个 msg1、msg2、msg3。
3.2 出列操作 RPOP即进行消费,消费的顺序是前辈先出(师长西席产先消费),出列利用的语法如下:
> RPOP msg_queue"msg1"> RPOP msg_queue"msg2"> RPOP msg_queue"msg3"> RPOP msg_queue(nil)
都消费完成之后,便是nil了。
3.3 消费及时性问题
不同于常规的MQ,具备订阅模式,消费者可以感知到有新的生产出来了,再进行消费。List的问题在于,生产者向行列步队插入数据的时候,List 并不会主动关照消费者,以是消费者做不到及时消费。为了担保消费的及时,可能须要做一个心跳包(1秒实行一次),不断地实行 RPOP 指令,当探测到有新就会取出进行消费,没有的时候就返回nil。但是这种也存在明显的短板,便是不断的调用 RPOP 指令,占用 I/O 资源和CPU资源。
比较好的办理办法便是在行列步队为空行列步队的时候,停息读取,等有入列的时候,规复取数和消费的事情,这样也避免了无效的资源摧残浪费蹂躏。Redis 供应了 BLPOP、BRPOP ,无数据的时候自动壅塞读取的命令,有新进入的时候,规复取数,如下:
# BRPOP key timeout BRPOP msg_queue 0
命令末了一个参数 timeout 是超时时间,单位是秒,如果 timeout 大于0,则到达指定的秒数纵然没有弹出成功也会返回,如果 timeout 的值为0,则会一贯壅塞等待其他连接向列表中插入元素, timeout 参数不许可为负数。
3.4 的重复消费问题目前 List 没有纯幂等的鉴别能力,但是可以通过以下两种方法来实现:
List为每一条天生一个 Glocal ID,重复的Glocal ID 不进行重复消费。Producer在生产的时候在中创建一个Glocal ID,当消费的时候把Glocal ID Record一下,后续的消费先判断再消费,避免重复消费同一个。这样就担保了对付同一条,消费者始终只处理一次,结果始终保持同等。3.5 的可靠性传输问题可靠性传输我们在MQ篇章用了一整节来先容持久化存储、ACK 、二次记录保障。这边我们也来看看Redis List中的可靠性传输的保障。Redis中短缺了一个确认(ACK)的机制,如果消费数据的时候运行崩溃了,没有确认机制,很可能这条就被错过了,无法担保数据的同等性。办理方案:Redis 供应了 RPOPLPUSH 指令,当List读取消息的时候,会同步的把该复制到其余一个List以作备份。全体操作过程是具备原子性的,避免读取消息了,但是同步备份不堪利。
如果涌现处理涌现故障的情形,在故障回答之后,可以从备份的List中复制连续消费。操作如下:
# 生产 msg1 msg2> LPUSH list_queue msg1 msg2 (integer) 2# 消费并同步到备份> RPOPLPUSH list_queue list_queue_bak"msg1"# 当发生故障的时候去消费备份的数据,可以消费到> RPOP list_queue_bak"msg1"
如果消费成功则把 list_queue_bak 删除即可,如果发生故障,则可以连续从 list_queue_bak 再次读取消息处理。
4 利用 Redission 实现行列步队能力
这边以Java SpringBoot为例子进行解释,可以参考官方文档。
4.1 添加maven依赖 和 配置基本连接# maven信息<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.16.8</version></dependency>
# 基本配置spring: application: name: redission_test redis: host: x.x.x.x port: 6379 ssl: false password: xxxx.xxxx
4.2 Java程序实现
@Slf4j@Servicepublic class RedisQueueService { @Autowired private RedissonClient redissonClient; private static final String REDIS_QUEUE = "listQueue"; / 生产 @param msg / public void msgProduce(String msg) { RBlockingDeque<String> blockDeque = redissonClient.getBlockingDeque(REDIS_QUEUE); try { blockDeque.putFirst(msg); // 写入行列步队头部 } catch (InterruptedException e) { log.error(e.printStackTrace()); } } / 消费:壅塞 / public void msgConsume() { RBlockingDeque<String> blockDeque = redissonClient.getBlockingDeque(REDIS_QUEUE);Boolen isCheck = true; while (isCheck) { try { String msg = blockDeque.takeLast(); // 从行列步队中取出 } catch (InterruptedException e) { log.error(e.printStackTrace()); } } }
5 总结Redis中利用List 数据构造实现行列步队,知足FIFO的处理机制,利用 RPOP 进行读取。利用 BRPOP 指令处理消费及时性问题利用 BRPOPLPUSH 命令进行数据备份,办理可靠性传输问题。相对付专业的MQ,如kafka和RocketMQ,处理能力会差很多。以是在在量不大的场景中利用,可以作为一个比较不错的行列步队办理方案。但是过于繁芜的场景随意马虎造成堆积。
为帮助开拓者们提升口试技能、有机会入职BATJ等大厂公司,特殊制作了这个专辑——这一次整体放出。
大致内容包括了: Java 凑集、JVM、多线程、并发编程、设计模式、Spring百口桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat等大厂口试题等、等技能栈!
欢迎大家关注"大众年夜众号【Java烂猪皮】,回答【666】,获取以上最新Java后端架构VIP学习资料以及视频学习教程,然后一起学习,一文在手,口试我有。
每一个专栏都是大家非常关心,和非常有代价的话题,如果我的文章对你有所帮助,还请帮忙点赞、好评、转发一下,你的支持会勉励我输出更高质量的文章,非常感谢!