提到RabbitMQ,我们就不得不先说一下AMQP协议和JMS规范。
- JMS (Java Message Service) 应用程序接口,是java平台中关于面向消息中间件(MOM, Message oriented Middleware)的API,绝大多数MOM提供商都支持。类似于JDBC
- AMQP全称高级消息队列协议(Advanced message queuing protocol),是一种标准,跨语言,类似于http协议
Java 应用rabbitMq时同时实现JMS规范,和AMQP协议
AMQP协议有如下几个概念,同时也存在于rabbitmq中
Publisher: 消息发送者,将消息发送到Exchange 并制定RoutingKey,以便queue可以接受到指定的消息。
Consumer: 消息消费者,从queue获取消息,一个consumer可以订阅多个queue以从多个queue中接受消息。
Server: 一个具体的MQ服务实列,也成为Broker.
Virtual host: 虚拟主机,一个server下可以多个虚拟主机。用于隔离不同项目,一个virtual host通常包含多个Exchange, message queue.
Exhange: 交换器,接收producer发送来的消息,把消息转发到对应的message queue中。
Routing Key: 路由键,用于指定消息路由规则(Exchange 将消息路由到具体的queue中),通常需要和具体的Exchange 类型,binding的routing key结合起来使用
Bindings: 指定了Exchange 和 queue之间的绑定关系。Exchange 根据消息的routing key和binding配置来决定把消息分派到那个具体的queue中
Message queue: 实际存储消息的容器,并把消息传递给最终的consumer。
Channel: 信道, 信道是建立在真实的TCP连接内的虚拟连接。AMQP的命令都是通过信道发送出去的,每条信道都会被指派一个唯一ID,不论是发布消息、订阅队列还是接收消息都是通过信道完成的。一个TCP连接下包含多个信道,实现共用TCP、减少TCP创建和销毁的开销。
RabbitMQ 在微服务多实例中的模型
微服务中,一个服务往往由多个实例共同组成,每个实例中都可以包含整个服务的所有queue,每个queue可以有多个Consumer.
E.G.
- 如果一个服务有1个queue,该queue的ConcurrentConsumers 设置为8,该服务有6个instance,那么正常情况下该服务对应的该queue至少有48个consumers。
- 每个instance既可以是生产者同时也可以是消费者,mq存在意义之一就是当某个instance接收到的自身难以在短时间内处理完的请求时,这个instance就可以作为生产者
将数据分段,让更多消费者来消费它。 - Perfetch: 它的作用就是预取消息数量,如某consumer-n,它一次性可以去255个消息去消费,那么被取中的消息就不可能再被其他消费者取到,那么为了更好的负载均衡
往往我们可以不把这个值设置太大,因为当某一consumer预取得数量太多,它很有可能没有能力在短时间内去消费它,造成消息在单个consumer内部堆积,而其他的消
费者很可能取的数量不多过早的就完成了任务,而处于空闲状态,造成资源的浪费。方然适当的多设置这个数量可以减少consumer和queue之间的交互,这也是这个值
需要根据实际情况去设置的原因。 - ConcurrentConsumers 和MaxConcurrentConsumers 分别是设置单个实例内部最少消费者数量和最大消费者数量。这个数量的设置同样需要根据实际情况而定 ,以达到
更好的资源利用率和用户满意度