RabbitMQ Channel 和 Exchange

channel 

有了TCP连接后,还需要channel的原因如下:

创建和销毁TCP连接很耗时;
打开太多TCP连接,耗操作系统资源,并发量大到一定程度,系统的吞吐量会降低;
使用一个connection多channel的方式,可以提升连接的利用率。
因此采用多个channel多路复用一个TCP连接的方式才比较合理

exchange(交换机)

生产者发消息发往交换机,交换机会自己投递消息到绑定的queue队列

1.exchange根据什么规则把消息投递到哪些queue中?
exchange有4种类型
direct:
对routing_key进行严格匹配,当消息来到的时候,只有exchange与某queue绑定的routing_key完全匹配才将消息投递到该queue

topic:
对routing_key进行通配符模糊匹配,满足条件的queue都能收到消息,这里的routing_key以"."分隔,*匹配一个单词,#匹配多个单词,如果同一个queue满足多个条件不会被投递多次

一下图为例,如果消息的routingkey是quick.orange.rabbit,那么Q1 Q2都会收到这条消息。

如果消息的routingkey是quick.orange.fox,那么Q1会收到这条消息

headers:
根据消息体内的headers属性匹配,绑定的时候可以制定键值对。不依赖routing_key匹配。

没有图,大致逻辑与direct差不多,只不过不是用的routing_key来匹配

fanout:
转发消息到所有绑定队列,不依赖routing_key匹配

在不需要路由的时候,一般是使用的这个类型的exchange。

发布订阅:两个queue绑定到同一个exchange上,那么同一个消息被发送到exchange后,exchange会把这个消息发给绑定的所有队列,两个消费者,一人消费一个队列,这就在这两个消费者之间达到了发布订阅的效果

 竞争消费:两个消费者消费同一个队列,这就达到了这两个消费者之间的竞争消费效果。注意,下图没有画exchange,实际上在写代码的时候不显示指定exchange的数据是发送到一个默认的exchange上的。

2.exchange持久化怎么搞?
如果不设置持久化,broker挂了,再重启,这个exchange就不存在了。

在客户端声明exchange的时候有个入参来控制是否持久化

而autoDelete则是,当没有queue绑定的时候是否自动删除这个exchange

3.生产者ACK机制?(事务或者confirm机制)
rabbitmq生产者确保消息一定送达,这个需要借助Server和MQ的交互实现(tx-select/commit, ok/fail)

4.投递方法(basicPublish)中的mandatory和immediate
mandatory
当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返回给生产者(Basic.Return + Content-Header + Content-Body);

当mandatory设置为false时,出现上述情形broker会直接将消息扔掉。

immediate
当immediate标志位设置为true时,如果exchange在将消息路由到queue(s)时发现对于的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或者多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。

换句话说,无法找到一个消费者时,消息返还给生产者

你可能感兴趣的:(rabbitmq,分布式,java)