RabbitMQ消息类型

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. Rabbitmq 是什么?

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件). AMQP(Advanced Message Queuing Protocol) , 一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计, RocketMQ,ActiveMQ, ZeroMQ, Kafaka, 等消息队列都是AMQP协议的实现。

2. 为什么用MQ?

在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。 例如:点赞/评论/阅读数等,要求实时性不高的,只要求最终一致性的业务。

3. rabbitMQ 名词解析

3.1 virtual host

类似DB中的schema, JAVA中的namespace

3.2 exchange

交换机,消费者发送消息到exchange

3.3 routeint key (binding key - 生产者端) 路由

生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联合使用才能最终生效。

在Exchange Type与binding key固定的情况下(在正常使用时一般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时, 通过指定routing key来决定消息流向哪里。RabbitMQ为routing key设定的长度限制为255 bytes。

3.4 queue

队列用于储存消息

4. Exchange Types

Exchange Types有 fanout、direct、topic、headers这四种类型

4.1 fanout message

广播模式,fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中,所以不管你的生产者端的bingding key 和 消费者端的routing key.

参考下面的图片:

RabbitMQ消息类型_第1张图片

生产者发送一个消息会被消费者C1 & C2接收到。

4.2 direct message

direct类型的Exchange路由规则也很简单,它会把消息路由到那些binding key与routing key完全匹配的Queue中, routing(binding) key 最大长度 255 bytes。

RabbitMQ消息类型_第2张图片

根据生产者中binding key 来和消费者端 routing key 做精确匹配(equal)。

4.3 topic message

direct message 是 binding key == routing key, topic message是like, 其中routing key中可以带 * 和 # 来做模糊匹配, “*”用于匹配一个单词,“#”用于0~N个单词.

RabbitMQ消息类型_第3张图片

4.4 headers message

headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

RabbitMQ消息类型_第4张图片

headers 图片引用自

headers x-match 决定是否进入到相应队列, x-match = any, key*/value* 只要有一个符合就行, x-match =all key*/value* 要求 >= 条件

5. RPC

MQ本身是基于异步的消息处理,前面的示例中所有的生产者(P)将消息发送到RabbitMQ后不会知道消费者(C)处理成功或者失败,但实际的应用场景中, 业务上很可能需要一些同步处理,需要同步等待服务端将消息处理完成后再进行下一步处理。这相当于RPC(Remote Procedure Call,远程过程调用)。 在RabbitMQ中也支持RPC。

RabbitMQ消息类型_第5张图片

根据消息属性上的 replyTo & correctionId 标识,返回给生产者(P)端,让生产者端继续执行之后的业务逻辑(可以同步/异步).

6. Dead letter message

用来做延时任务

channel.exchangeDeclare("some.exchange.name", "direct");

Map args = new HashMap();
# expire time (ms)
args.put("x-message-ttl", 60000);

args.put("x-dead-letter-exchange", "some.exchange.name");
# without consumer listener queue: myqueue, will redirect to dead leter routing key
args.put("x-dead-letter-routing-key", "some-routing-key");

channel.queueDeclare("myqueue", false, false, false, args);

7. CAP

7.1 一致性

consumer 接口应该考虑幂等性和最终一致性。 例如:consumer 操作 DB 应该提前定义主键, insert or update

7.2 高可用

为了达到高可用,合理的设置每个consumer 的线程池大小和prefetch count.


# set consumer thread pool
ExecutorService es = Executors.newFixedThreadPool(20);
Connection conn = factory.newConnection(es);

# consumer 同时允许处理多少条未消费的消息
channel.basicQos(10); // Per consumer limit

7.3 分区容错性

启动多个consumer listener, 一个consumer down了,还能正常的使用。

转载于:https://my.oschina.net/kaishui/blog/3037858

你可能感兴趣的:(RabbitMQ消息类型)