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 ==> snd_protocol_header</code>
<code> </code><code>--> send protocol.header!</code>
<code>6040: conn_state change snd_protocol_header ==> rcv_connection_start_method</code>
<code> </code><code><-- recv connection.start method frame!</code>
<code>6040: conn_state change rcv_connection_start_method ==> snd_connection_start_rsp_method</code>
<code> </code><code>--> send connection.start-ok method frame!</code>
<code>6040: conn_state change snd_connection_start_rsp_method ==> rcv_connection_tune_method</code>
<code>drive_machine: wait</code><code>for</code> <code>connection.tune method another 10 seconds!!</code>
<code> </code><code><-- recv connection.tune method frame!</code>
<code>6040: conn_state change rcv_connection_tune_method ==> snd_connection_tune_rsp_method</code>
<code> </code><code>--> send connection.tune-ok method frame!</code>
<code>6040: conn_state change snd_connection_tune_rsp_method ==> snd_connection_open_method</code>
<code> </code><code>--> send connection.open method frame!</code>
<code>6040: conn_state change snd_connection_open_method ==> rcv_connection_open_rsp_method</code>
<code> </code><code><-- recv connection.open-ok method frame!</code>
<code>6040: conn_state change rcv_connection_open_rsp_method ==> snd_channel_open_method</code>
<code> </code><code>--> send channel.open method frame!</code>
<code>6040: conn_state change snd_channel_open_method ==> 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><-- recv channel.open-ok method frame!</code>
<code>6040: conn_state change rcv_channel_open_rsp_method ==> idle</code>
<code>drive_machine: [conn_idle] --- [producer]: find something to send!</code>
<code>6040: conn_state change idle ==> snd_basic_publish_method</code>
<code> </code><code>--> send basic.publish method frame!</code>
<code>6040: conn_state change snd_basic_publish_method ==> snd_basic_content_header</code>
<code> </code><code>--> send content-header frame!</code>
<code>6040: conn_state change snd_basic_content_header ==> snd_basic_content_body</code>
<code> </code><code>--> send content-body frame!</code>
<code>6040: conn_state change snd_basic_content_body ==> 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 ==> snd_protocol_header</code>
<code>8088: conn_state change snd_protocol_header ==> 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 ==> snd_connection_start_rsp_method</code>
<code>8088: conn_state change snd_connection_start_rsp_method ==> rcv_connection_tune_method</code>
<code>8088: conn_state change rcv_connection_tune_method ==> snd_connection_tune_rsp_method</code>
<code>8088: conn_state change snd_connection_tune_rsp_method ==> snd_connection_open_method</code>
<code>8088: conn_state change snd_connection_open_method ==> rcv_connection_open_rsp_method</code>
<code>need to code something!</code>
<code>8088: conn_state change rcv_connection_open_rsp_method ==> snd_channel_open_method</code>
<code>8088: conn_state change snd_channel_open_method ==> rcv_channel_open_rsp_method</code>
<code>8088: conn_state change rcv_channel_open_rsp_method ==> idle</code>
<code>8088: conn_state change idle ==> snd_basic_publish_method</code>
<code>8088: conn_state change snd_basic_publish_method ==> snd_basic_content_header</code>
<code>8088: conn_state change snd_basic_content_header ==> snd_basic_content_body</code>
<code>8088: conn_state change snd_basic_content_body ==> rcv_basic_return_method</code>
<code> </code><code><-- 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 ==> idle</code>
该图显示了在 basic.publish 中设置 mandatory 为 true 。
该图中显示了当 queue 不存在时,服务器返回 basic.return + content.header + content.body 的内容。
下图为正常情况和异常情况。