[云计算]OpenStack - RabbitMQ
参考:
RabbitMQ核心概念以及工作原理:https://www.jianshu.com/p/256c502d09cd
RabbitMQ在OpenStack中的位置(Queue)
什么是RabbitMQ?
-
MQ全程为Message Queue,应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。
-
在OpenStack中,服务内组件之间的消息全部通过MQ来进行转发,包括控制、查询、监控指标等。
-
RabbitMQ是MQ实现的一种,它具有如下的特点:
- 更好的Message(可靠性、灵活的route、集群)
- 使用相对简单
- 支持主流的操作系统:Windows、Linux
- 支持大量的平台:Java、Python、.Net等等
- 开源和商业支持
-
OpenStack支持的MQ类型:
- RabbitMQ
- ZeroMQ
RabbitMQ中的基本概念
组件
- Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
- Queue:消息队列载体,每个消息都会被投入一个或者多个队列中。
- Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
- Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
- Producer:消息生产者,就是投递消息的程序。
- Consumer:消息消费者,就是接受消息的程序。
- Vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
- Connection:就是一个TCP连接。Producer和Consumer都是通过TCP连接到RabbitMQ Server的。(程序的起始就是建立这个TCP连接)。
- Channel:消息通道,是在TCP连接中的虚拟连接,在客户端的每个TCP连接里,可建立多个channel,每个 channel代表一个会话任务。
交换机(Exchange)的类型
- 直接(Direct):直接交换机通过消息上的路由键直接对消息进行分发。
- 扇出(Fanout):一个扇出交换机会将消息发送到所有和它进行绑定的队列上。
- 主题(Topic):这个交换机会将路由键和绑定上的模式进行通配符匹配。
- 消息头(Headers):消息头交换机使用消息头的属性进行消息路由。
RabbitMQ的服务端与客户端
服务端
- 持久化
- Exchange持久化
- Queue持久化
- Message持久化
- channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
- ACK
- 启用ack之后,客户端接收到消息之后,需要发送ack给服务器
- 如果没有收到ack,服务器会将这条消息发送给另外的客户端
- 默认启用ack
- channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
- Fair dispatch
- 默认采用Round-robin方式,是循环分发,如果有Consumer工作比较重,那么就会导致有的Consumer基本没事可做,有的Consumer却是毫无休息的机会。
- Fair dispatch确保每个Consumer 每一时间点只处理一条消息。未收到ACK前,不会分发新消息。
- channel.basic_qos(prefetch_count=1)
客户端
- oslo.messaging:提供rpc和notification API Icehouse从各个组件内剥离出来
- Kombu:抽象概念,支持虚拟消息队列,扩展性高
- Amqp:Python库,实现amqp协议
RabbitMQ的工作流程
生产者发送消息
1、生产者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)
2、生产者声明一个交换器,并设置相关属性,比如交换机类型、是否持久化等
3、生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等
4、生产者通过路由键将交换器和队列绑定起来
5、生产者发送消息至 RabbitMQ Broker,其中包含路由键、交换器等信息
6、相应的交换器根据收到的路由键查找相匹配的队列
7、如果找到,则将从生产者发送过来的消息存入相应的队列中
8、如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
9、关闭信道
10、关闭连接
消费者接收消息
1、消费者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)
2、消费者向 RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作
3、等待 RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息
4、消费者确认(ack)接收到的消息
5、RabbitMQ 从队列中删除相应已经被确认的消息
6、关闭信道
7、关闭连接
RabbitMQ的消息收发完整流程:call
- api发送消息
- mq-server收到消息
- compute收到消息
- 执行函数
- 返回执行结果
- api收到compute的执行结果
RabbitMQ的消息收发完整流程:cast
- api发送消息
- mq-server收到消息
- compute收到消息
- 执行函数