AMQP 中的Message路由
AMQP 中Message的路由过程和 Java 开 发者熟悉的 JMS 存在一些差别, AMQP 中增加了 Exchange 和 Binding 的角色。生产者把MessagePublish 到 Exchange 上,Message最终到达Queue 并被消费者接收,而 Binding 决定交 换器的Message应该发送到那个Queue
Exchange 类型
Exchange分发Message时根据Type的不同分发策略有区别,目前共四种Type:direct、 fanout、topic、headers 。headers 匹配 AMQP Message的 header 而不是路由键, headers 交换器和 direct 交换器完全一致,但Performance差很多,目前几乎用不到了,所以直接 看另外三种Type:
Direct Exchange

Message中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器 就将Message发到对应的Queue中。路由键与队 列名完全匹配,如果一个Queue绑定到交换 机要求路由键为“dog”,则只转发 routing key 标记为“dog”的Message,不会转发 “dog.puppy”,也不会转发“dog.guard” 等等。它是完全匹配、单播的Pattern
Fanout Exchange

每个发到 fanout Type交换器的Message都 会分到所有绑定的Queue上去。fanout 交 换器不处理路由键,只是简单的将Queue 绑定到交换器上,每个发送到交换器的 Message都会被转发到与该交换器绑定的所 有Queue上。很像子网广播,每台子网内 的主机都获得了一份复制的Message。 fanout Type转发Message是最快的
Topic Exchange

topic 交换器通过Pattern匹配分配Message的 路由键属性,将路由键和某个Pattern进行 匹配,此时Queue需要绑定到一个Pattern上。 它将路由键和绑定键的字符串切分成单 词,这些单词之间用点隔开。它同样也 会识别两个通配符:符号“#”和符号 “*”。#匹配0个或多个单词,*匹配一 个单词
RabbitMQ消息确认机制-可靠抵达
保证Message不Lost,可靠抵达,可以UsageTransactionMessage,Performance下降250倍,为此引入确认Mechanism publisher confirmCallback 确认Pattern publisher returnCallback 未投递到 queue 退回Pattern consumer ackMechanism

1、发送端-可靠抵达-ConfirmCallback
• spring.rabbitmq.publisher-confirms=true • 在Create connectionFactory 的时候Settings PublisherConfirms(true) 选项,开启confirmcallback 。 • CorrelationData:用来表示当前Message唯一性。 • Message只要被 broker 接收到就会Execute confirmCallback,如果是cluster Pattern,需要所有broker 接收到才会调用 confirmCallback。 • 被 broker 接收到只能表示 message 已经到达Server,并不能保证Message一定会被投递到目标 queue 里。所以需要用到接下来的 returnCallback 。
2、发送端-可靠抵达-ReturnCallback
• spring.rabbitmq.publisher-returns=true • spring.rabbitmq.template.mandatory=true • confrim Pattern只能保证Message到达 broker,不能保证Message准确投递到目标queue里。在有些业务场景下,我们需要保证Message一定要投递到目标queue 里,此时就需要用到return 退回Pattern。 • 这样如果未能投递到目标 queue 里将调用 returnCallback ,可以记录下详细到投递Data,定期的巡检或者自动纠错都需要这些Data。
3、消费端-可靠抵达-Ack消息确认机制
消费者Get到Message,成功处理,可以回复Ack给Broker •basic.ack用于肯定确认;broker将移除此Message •basic.nack用于否定确认;可以指定broker是否丢弃此Message,可以批量 •basic.reject用于否定确认;同上,但不能批量 •默认自动ack,Message被消费者收到,就会从broker的queue中移除 •queue无消费者,Message依然会被Storage,直到消费者消费 •消费者收到Message,默认会自动ack。但是如果无法确定此Message是否被处理完成,或者成功处理。我们可以开启手动ackPattern •Message处理成功,ack(),接受下一个Message,此Messagebroker就会移除 •Message处理失败,nack()/reject(),重新发送给其他人进行处理,或者Fault Tolerance处理后ack •Message一直没有调用ack/nackMethod,broker认为此Message正在被处理,不会投递给别人,此时客户端断开,Message不会被broker移除,会投递给别人
详细Usage可参考,springboot整合RabbitMQ 及Introduction to RabbitMQ