概述
消息队列已经逐步成为企业系统内部通信的核心手段。
简单的消息队列模型:
举例购物网站购物后,需要发送短信通知。其中图中的流程A就是发短信的业务,将其封装为一条消息A1,并放到消息队列,消息队列按照一定处理顺序处理消息,若成功则消息A1被处理;如果因短信调用端接口出现问题,短信发送超时或短时间内达到上限,则导致失败,可以重新将消息放入消息队列。
其中的一些待处理的细节:
- 在消息中指定最小的执行时间。可减少重新尝试的次数。
- 需对消息队列对消息的处理速度,即短时间内短信发送的上限。
该例使用消息队列的好处:
- 实现网站主业务与短信通知业务的异步解耦。
- 简化设计。短信通知业务交由消息队列处理。
- 通过消息保持了事务最终一致性。即使失败也会重新尝试,保证短信业务的执行完成。
- 若还需要邮件通知业务,可以与短信通知业务并行处理;而不必同步等待,,增强系统的异步处理能力,减少甚至消灭并发现象。
消息队列使用场景
- 异步处理:如用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式
- 应用解耦:如用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。
- 流量销锋:如秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
- 日志系统:如Kafka的应用,解决大量日志传输的问题。
- 信息通讯:如实现点对点消息队列,或者聊天室等。
- 实现最终一致性:可按批次进行消息处理,并保证最终一致性。支持最终一致性的MQ可以用来处理对延迟非敏感的分布式事务场景。相对于较笨重的分布式事务,其不失为较优的处理方式。
- 广播:消息队列的基础功能。
- 错峰与流控:通过中间件系统实现。
消息队列并不是万能的:
对于需要强事务保证,而且对延迟敏感事务,RPC是由于消息队列MQ的。
消息队列特性
- 业务无关:只做消息分发;
- FIFO:与缓存区Buffer的本质区别,即先投递先到达;
- 容灾:结点的动态增删和消息的持久化
- 性能:吞吐量提升,系统内部通信效率提高。
消息队列举例
Kafka
RabbitMQ
ActiveMQ
RocketMQ
等
初识Kafka
Kafka是Apache基金会下的一个开源项目。
是一个高性能跨语言的分布式发布订阅(PUB/SUB)的消息队列系统。
其处理流程图为;
Kafka特性
- 可快速持久化。通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。
- 高吞吐量。即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
- 完全的分布式系统。它的Broker、Producer、Consumer都原生地支持分布式,自动支持负载均衡。
- 支持Hadoop的数据并行加载。可通过hadoop的并行加载机制统一处理在线、离线的消息。
- 支持通过Kafka服务器和消费机集群来分区消息。
Kafka相关术语
对应于上图:
- Broker
Kafka集群包含一个或多个服务器,这种服务器被称为broker。 - Topic
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处) - Partition
Partition是物理上的概念,每个Topic包含一个或多个Partition. - Producer
负责发布消息到Kafka broker - Consumer
消息消费者,向Kafka broker读取消息的客户端。 - Consumer Group
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
参考自百度百科
初识RabbitMQ
相对于其他消息队列,RabbitMQ有自己的服务器的管理界面。
处理流程图如下:
其中的概念说明:
- Broker:简单来说就是消息队列服务器实体。
- Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
- Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
- Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
- Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
- vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
- producer:消息生产者,就是投递消息的程序。
- consumer:消息消费者,就是接受消息的程序。
- channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
- ExchangeType(关键):交换策略。指定exchange分发消息到哪一个或多个队列中。其有四种类型:Direct , Fanout , Topic , Handers。
其处理流程为:
- 客户端连接到消息队列服务器,打开一个channel。
- 客户端声明一个exchange,并设置相关属性。
- 客户端声明一个queue,并设置相关属性。
- 客户端使用RoutingKey,在exchange和queue之间建立好绑定关系。
- 客户端投递消息到exchange。
- exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。
- 客户端只需要负责处理消息。