消息队列
消息队列的特性
- 业务无关性: 不需要考虑上层的业务模型,只需要做好消息分发即可。
- FIFO 先入先出队列。
- 容灾 节点的动态增删和消息的持久化。
- 性能 消息队列的吞吐量大,通信效率更高
应用场景
- 任务处理类系统,将用户发起的请求接收过来存储到消息队列中,发送给后端服务器进行处理
- 调用远程系统,由于网络波动等,同意发送请求
- 业务要求触发其他模块时,其他微服务的相应速度可能跟不上,可以将来不及处理的消息暂存至队列中,进行缓冲,直接返回用户成功。再慢慢去队列中对消息进行处理。如短信发送功能等。
系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消息队列,作为抽象层,弥合双方的差异。“ 消息 ”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。消息被发送到队列中,“ 消息队列 ”是在消息的传输过程中保存消息的容器 。
消息队列的优势
-
提高系统的相应速度
生产者将消息往消息往队列里一扔,就可以立马返回,响应用户了。无需等待处理结果。
- 生产者订阅,有结果后通知
- 用户自己去取
-
提高系统的稳定性
电商系统和生产系统之间的网络有可能掉线,生产系统可能会因维护等原因暂停服务。如果不使用消息队列,电商系统数据发布出去,顾客无法下单,影响业务开展。两个系统间不应该如此紧密耦合。应该通过消息队列解耦。同时让系统更健壮、稳定。
-
异步 解耦 消峰
消息队列位于逻辑节点与数据库之间。
- 逻辑节点与数据库的交互会有大量的IO,即使把与Db交互的模块耦合在逻辑节点内,其实现对你来说是黑盒,如果内部是同步实现的话,一次存盘操作,服务器会直接挂掉
- 把这个模块做到一个线程里挂在逻辑节点上。这样其实逻辑节点跟这个Db前端模块的交互就会基于一个比较原始的消息队列。但是这样还有一个坏处,那就是这两种任务一种是计算密集的(玩家的逻辑处理)、一种是IO密集的(只负责写入读取数据库),搞到一个节点中,扩展起来会非常麻烦,而且耦合度太高。比如说现在发现场景放单节点上有瓶颈,要按场景分节点,那么这种挂在上面的数据模块怎么跟其他场景的交互。
- 在分布式系统中,一次分布式事务关联的是多个节点,其中每一个节点出现问题都会成为整个事务处理流程中的瓶颈。如果逻辑节点与数据库之间没有一个起到缓冲作用的节点,那就是每次操作都要访问数据库。
- 并发量上来之后,会造成chain reaction,大量的并发不会直接挂掉你的数据库节点,但是会拖慢速度,降低吞吐量,一个玩家的请求由于处理时间太长,导致玩家放弃重试,但是对于后端来说,对该玩家之前的处理过程消耗的资源就全部浪费了,陷入恶性循环。
为什么需要分布式
-
单系统内部环境部署需要
单系统内部,为了更好的性能、为了避免单点故障,多为集群环境。集群环境中,应用运行在多台服务器的多个JVM中;数据也保存在各种类型的数据库或非数据库的多个节点上。为了满足多节点协作需要,需要提供分布式的解决方案。 -
多系统协作需要
消息队列中的数据需要在多个系统间共享数据才能发挥价值。所以必须提供分布式通信机制、协同机制。
分布式需要解决的问题
-
并发
需进行良好的并发控制。确保“线程安全“。不要出现一个订单被出货两次。
-
容错
控制好单点故障,确保数据安全。 -
拓展性
便捷扩容 -
统一机制
需定义简单的,语义明确的,业务无关的,恰当稳妥的统一的访问方式。
常见的消息队列对比选择
功能 | RabbitMQ(开源) | Kafka | RocketMQ | Apache RocketMQ(开源) | Apache Kafka(开源) |
---|---|---|---|---|---|
安全防护 | √ | √ | √ | × | × |
主子账号支持 | × | √ | √ | × | × |
可靠性 | 同步刷盘 | 同步刷盘、同步双写 | 同步刷盘、同步双写 | 同步刷盘、异步刷盘 | 异步刷盘、丢数据概率高 |
横向拓展能力 | LVS负载均衡 | 支持平滑扩展(百万级QPS) | 支持平滑扩展(百万级QPS) | 支持 | 支持 |
可用性 | 好 | 非常好 | 非常好 | 好 | 好 |
Low Latency | × | √ | √ | × | × |
消息模型 | Push/Pull | Push/Pull | Push/Pull | Push/Pull | Pull |
定时消息 | √ | × | √(毫秒级) | √ | × |
事务消息 | × | × | 支持 | × | × |
顺序消息 | × | × | √ | √ | √ |
全链路消息轨迹 | × | × | √ | × | × |
消息堆积能力 | |||||
消息堆积查询 | × | √ | √ | √ | × |
消息回溯 | × | √ | √ | √ | × |
消息重试 | √ | × | √ | √ | × |
死信队列 | √ | × | √ | √ | × |
性能(常规) | 一般 万级QPS | 非常好 百万级 QPS | 非常好 百万级 QPS | 非常好 十万级 QPS | 非常好 百万级 QPS |
性能(万级topic) | 低 | 非常好 百万级 QPS | 非常好 百万级 QPS | QPS | 低 |
性能(海量消息堆积) | 低 | 非常好 百万级 QPS | 非常好 百万级 QPS | 非常好 十万级 QPS | 低 |