消息队列 - 阿里RocketMq
阿里RocketMq是基于Apache RocketMQ构建的低延迟、高并发、高可用、高可靠的分布式消息中间件。
可以基于tcp协议和http协议。公司采用tcp协议。
tcp协议的有地域限制。TCP协议客户端接入点仅在公网地域有公网接入点,其余地域只提供内网接入点,HTTP协议在各地域均提供公网和内网接入点。
一、核心概念
-
topic: 消息主题,一级消息类型,生产者向其发送消息。
-
生产者:消息发布者。
-
消费者:消息消费者。
-
消息:生产者 向 topic发送并最终传送到消费者的数据和某些 属性的组合。
-
消息属性:生产者可以为消息定义的属性,包含message Key 和 Tag。
-
group:一类生产者或消费者,这类生产者或消费者消费同一类消息,且消息发布或订阅的逻辑一致。
要求统一group的消费者或者生产者的topic、tag完全一致包括顺序。
二、应用场景
-
削峰填谷
诸如秒杀、抢红包、企业开门红等大型活动时皆会带来较高的流量脉冲,或因没做相应的保护而导致系统超负荷甚至崩溃,或因限制太过导致请求大量失败而影响用户体验,消息队列RocketMQ版可提供削峰填谷的服务来解决该问题。
-
异步解耦
交易系统作为淘宝和天猫主站最核心的系统,每笔交易订单数据的产生会引起几百个下游业务系统的关注,包括物流、购物车、积分、流计算分析等等,整体业务系统庞大而且复杂,消息队列RocketMQ版可实现异步通信和应用解耦,确保主站业务的连续性。
-
顺序收发
细数日常中需要保证顺序的应用场景非常多,例如证券交易过程时间优先原则,交易系统中的订单创建、支付、退款等流程,航班中的旅客登机消息处理等等。与先进先出FIFO(First In First Out)原理类似,消息队列RocketMQ版提供的顺序消息即保证消息FIFO。
-
分布式事务一致性
交易系统、支付红包等场景需要确保数据的最终一致性,大量引入消息队列RocketMQ版的分布式事务,既可以实现系统之间的解耦,又可以保证最终的数据一致性。
-
大数据分析
数据在“流动”中产生价值,传统数据分析大多是基于批量计算模型,而无法做到实时的数据分析,利用阿里云消息队列RocketMQ版与流式计算引擎相结合,可以很方便的实现业务数据的实时分析。
-
分布式缓存同步
天猫双11大促,各个分会场琳琅满目的商品需要实时感知价格变化,大量并发访问数据库导致会场页面响应时间长,集中式缓存因带宽瓶颈,限制了商品变更的访问流量,通过消息队列RocketMQ版构建分布式缓存,实时通知商品数据的变化。
三、消息问题
消息丢失问题
采用消息重试机制。
Consumer消费某条消息失败,则消息队列RocketMQ版会在重试间隔时间后,将消息重新投递给Consumer消费,若达到最大重试次数后消息还没有成功被消费,则消息将被投递至死信队列。
- 重试间隔:消息消费失败后再次被消息队列RocketMQ版投递给Consumer消费的间隔时间。
- 最大重试次数:消息消费失败后,可被消息队列RocketMQ版重复投递的最大次数。
重试间隔和最大重试次数和选择的协议有关。
tcp协议:
顺序消息:重试间隔可自定义suspendTimeMillis,单位毫秒,默认1s,最大重试次数可自定义,默认Interger.MAX.
无序消息:重试间隔不可自定义,取值范围1~2小时,最大重试次数可自定义,默认值16.
重复消费问题
消息幂等,需要根据业务唯一key对消息做幂等处理,可以设置消息的key为业务唯一key比如订单号。
消息重复的场景:
-
发送时消息重复
当一条消息已被成功发送到服务端并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端应答失败。 如果此时生产者意识到消息发送失败并尝试再次发送消息,消费者后续会收到两条内容相同并且Message ID也相同的消息。
-
投递时消息重复
消息消费的场景下,消息已投递到消费者并完成业务处理,当客户端给服务端反馈应答的时候网络闪断。为了保证消息至少被消费一次,消息队列RocketMQ版的服务端将在网络恢复后再次尝试投递之前已被处理过的消息,消费者后续会收到两条内容相同并且Message ID也相同的消息。
-
负载均衡时消息重复(包括但不限于网络抖动、Broker重启以及消费者应用重启)
当消息队列RocketMQ版的Broker或客户端重启、扩容或缩容时,会触发Rebalance,此时消费者可能会收到重复消息。