RocketMQ是阿里参照kafka设计思想使用java实现的一套mq,目前主要多用于订单交易系统。在项目中,
我们通过引入消息中间件RocketMQ,保证数据库商品与ElasticSearch索引库、静态页三者之间的数据同步,
实现业务的解耦合。在商品上下架的时候,会发送MQ消息到索引库服务和静态页服务,分别进行相应的操作。
(一)应用场景
削峰填谷:比如如秒杀等大型活动时会带来较高的流量脉冲,如果没做相应的保护,将导致系统超负荷甚至崩溃。
如果因限制太过导致请求大量失败而影响用户体验,可以利用MQ 超高性能的消息处理能力来解决。
异步解耦:通过上、下游业务系统的松耦合设计,比如:交易系统的下游子系统(如积分等)出现不可用甚至宕机,
都不会影响到核心交易系统的正常运转。
顺序消息:与FIFO原理类似,MQ提供的顺序消息即保证消息的先进先出,可以应用于交易系统中的订单创建、支付、
退款等流程。
分布式事务消息:比如阿里的交易系统、支付红包等场景需要确保数据的最终一致性,需要引入 MQ 的分布式事务,
既实现了系统之间的解耦,又可以保证最终的数据一致性。
(二)RocketMQ消息重复问题
消息重复的原因:
消息领域有一个对消息投递的QoS(服务质量)定义,分为:最多一次(At most once)、至少一次(At least once)、
仅一次( Exactly once)。
MQ产品都声称自己做到了至少一次。既然是至少一次,那么就有可能发生消息重复。
有很多原因导致消息重复问题,比如:网络原因闪断,ACK返回失败等等故障,确认信息没有传送到消息队列,
导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者
不同的消息队列发送的确认信息形式不同:RocketMQ返回一个CONSUME_SUCCESS成功标志,
RabbitMQ是发送一个ACK确认消息。
(三)消息怎么去重
去重原则:使用业务端逻辑保持幂等性
幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用,
数据库的结果都是唯一的,不可变的。
只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样,需要业务端来实现。
去重策略:保证每条消息都有唯一编号(比如唯一流水号),且保证消息处理成功与去重表的日志同时出现。
(四)RocketMQ如何保证消息发送成功?
用数据库或者redis配合着解决:
怎么配合呢?咱们这边不是发送的商品的ID么,在发送之前把ID记录在数据库里面去,然后设置一个状态字段,
0代表这个消息发送中,然后监听端进行消费,消费成功后把这个字段在改为1。
(五)RocketMQ如何发送顺序消息?
RocketMQ是通过将“相同ID的消息发送到同一个队列,而一个队列的消息只由一个消费者处理“来实现顺序消息。
(六)几种MQ产品的对比
ActiveMQ是基于JMS协议实现的一个消息中间件,单机数据吞吐量在万级别;时效性是ms级;可用性高,
基于主从架构实现高可用;(消息可靠性)有较低的概率丢失数据;MQ 领域的功能极其完备 。
RabbitMQ是AMQP协议的领导实现,单机数据吞吐量在万级别;可以做到微秒级响应,延迟最低;
可用性高,基于主从架构实现高可用;(消息可靠性)基本不丢失数据;基于 erlang 开发,并发能力很强,性能极好,
延时很低。
rocketMQ是阿里使用java语言实现的一个mq产品,单机数据吞吐量在10 万级,支撑高吞吐;topic 可以
达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic;
时效性是ms级;可用性非常高,分布式架构;(消息可靠性)经过参数优化配置,可以做到 0 丢失;MQ 功能较为完善,
还是分布式的,扩展性好。
kafka是大数据领域应用较为广泛的一个mq产品,单机数据吞吐量在10 万级,高吞吐,一般配合大数据类的系统来进行
实时数据计算、日志采集等场景;topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic
数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源;时效性延迟在 ms 级以内;可用性非常高,分布式,
一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用;(消息可靠性)经过参数优化配置,可以做到 0 丢失;
功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用。