天天看点

【原创】RabbitMQ 之 mandatory

1.什么情况会导致 blackholed? 

两种情况:

声明 exchange 后未绑定任何 queue ,此时发送到该 exchange 上的 message 均被 blackholed ;

声明 exchange 后绑定了 queue ,但发送到该 exchange 上的 message 所使用的 routing_key 不匹配任何 binding_key ,则 blackholed 。

2.mandatory 的作用? 

      决定 message 将被如何处理,是被 exchange 直接丢弃还是由其发回给 producer (basic.return+content-header+content-body)。 

3.mandatory 和 publisher confirm 机制的区别? 

      publisher confirm 机制是用来确认 message 的可靠投递,mandatory 参数是用来确保在 queue 不存在的情况下,message 不会被 blackholed 。

queue 存在时,开启 mandatory 的情况:

<a href="http://my.oschina.net/moooofly/blog/147634#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

<code>[warn] evsignal_init: socketpair: no error</code>

<code>drive_machine: [conn_init]  --- </code><code>in</code> <code>tcp 3-way connecting!</code>

<code>drive_machine: [conn_connecting]  ---  connection timeout 1</code><code>time</code> <code>on socket(6040)</code>

<code>drive_machine: [conn_connected]  ---  connected on socket(6040)</code>

<code>6040: conn_state change   connected ==&gt; snd_protocol_header</code>

<code>  </code><code>--&gt; send protocol.header!</code>

<code>6040: conn_state change   snd_protocol_header ==&gt; rcv_connection_start_method</code>

<code>  </code><code>&lt;-- recv connection.start method frame!</code>

<code>6040: conn_state change   rcv_connection_start_method ==&gt; snd_connection_start_rsp_method</code>

<code>  </code><code>--&gt; send connection.start-ok method frame!</code>

<code>6040: conn_state change   snd_connection_start_rsp_method ==&gt; rcv_connection_tune_method</code>

<code>drive_machine: wait</code><code>for</code> <code>connection.tune method another 10 seconds!!</code>

<code>  </code><code>&lt;-- recv connection.tune method frame!</code>

<code>6040: conn_state change   rcv_connection_tune_method ==&gt; snd_connection_tune_rsp_method</code>

<code>  </code><code>--&gt; send connection.tune-ok method frame!</code>

<code>6040: conn_state change   snd_connection_tune_rsp_method ==&gt; snd_connection_open_method</code>

<code>  </code><code>--&gt; send connection.open method frame!</code>

<code>6040: conn_state change   snd_connection_open_method ==&gt; rcv_connection_open_rsp_method</code>

<code>  </code><code>&lt;-- recv connection.open-ok method frame!</code>

<code>6040: conn_state change   rcv_connection_open_rsp_method ==&gt; snd_channel_open_method</code>

<code>  </code><code>--&gt; send channel.open method frame!</code>

<code>6040: conn_state change   snd_channel_open_method ==&gt; rcv_channel_open_rsp_method</code>

<code>drive_machine: wait</code><code>for</code> <code>channel.open-ok method another 10 seconds!!</code>

<code>  </code><code>&lt;-- recv channel.open-ok method frame!</code>

<code>6040: conn_state change   rcv_channel_open_rsp_method ==&gt; idle</code>

<code>drive_machine: [conn_idle]  ---  [producer]: find something to send!</code>

<code>6040: conn_state change   idle ==&gt; snd_basic_publish_method</code>

<code>  </code><code>--&gt; send basic.publish method frame!</code>

<code>6040: conn_state change   snd_basic_publish_method ==&gt; snd_basic_content_header</code>

<code>  </code><code>--&gt; send content-header frame!</code>

<code>6040: conn_state change   snd_basic_content_header ==&gt; snd_basic_content_body</code>

<code>  </code><code>--&gt; send content-body frame!</code>

<code>6040: conn_state change   snd_basic_content_body ==&gt; idle</code>

<code>drive_machine: [conn_idle]  ---  [producer]: find nothing to send! wait</code><code>for</code> <code>another 10 seconds</code>

queue 不存在时,开启 mandatory 的情况:

39

40

41

42

43

<code>drive_machine: [conn_connecting]  ---  connection timeout 1</code><code>time</code> <code>on socket(8088)</code>

<code>drive_machine: [conn_connected]  ---  connected on socket(8088)</code>

<code>8088: conn_state change   connected ==&gt; snd_protocol_header</code>

<code>8088: conn_state change   snd_protocol_header ==&gt; rcv_connection_start_method</code>

<code>drive_machine: wait</code><code>for</code> <code>connection.start method another 10 seconds!!</code>

<code>8088: conn_state change   rcv_connection_start_method ==&gt; snd_connection_start_rsp_method</code>

<code>8088: conn_state change   snd_connection_start_rsp_method ==&gt; rcv_connection_tune_method</code>

<code>8088: conn_state change   rcv_connection_tune_method ==&gt; snd_connection_tune_rsp_method</code>

<code>8088: conn_state change   snd_connection_tune_rsp_method ==&gt; snd_connection_open_method</code>

<code>8088: conn_state change   snd_connection_open_method ==&gt; rcv_connection_open_rsp_method</code>

<code>need to code something!</code>

<code>8088: conn_state change   rcv_connection_open_rsp_method ==&gt; snd_channel_open_method</code>

<code>8088: conn_state change   snd_channel_open_method ==&gt; rcv_channel_open_rsp_method</code>

<code>8088: conn_state change   rcv_channel_open_rsp_method ==&gt; idle</code>

<code>8088: conn_state change   idle ==&gt; snd_basic_publish_method</code>

<code>8088: conn_state change   snd_basic_publish_method ==&gt; snd_basic_content_header</code>

<code>8088: conn_state change   snd_basic_content_header ==&gt; snd_basic_content_body</code>

<code>8088: conn_state change   snd_basic_content_body ==&gt; rcv_basic_return_method</code>

<code>  </code><code>&lt;-- recv basic.return method frame!</code>

<code>      </code><code>### reply_code: 312, reply_text: no_route, exchange=amq.direct, routing_key=test1</code>

<code>8088: conn_state change   rcv_basic_return_method ==&gt; idle</code>

该图显示了在 basic.publish 中设置 mandatory 为 true 。 

【原创】RabbitMQ 之 mandatory

该图中显示了当 queue 不存在时,服务器返回 basic.return + content.header + content.body 的内容。 

【原创】RabbitMQ 之 mandatory

下图为正常情况和异常情况。 

【原创】RabbitMQ 之 mandatory