1.什么情况会导致 blackholed?
两种情况:
- 声明 exchange 后未绑定任何 queue ,此时发送到该 exchange 上的 message 均被 blackholed ;
- 声明 exchange 后绑定了 queue ,但发送到该 exchange 上的 message 所使用的 routing_key 不匹配任何 binding_key ,则 blackholed 。
决定 message 将被如何处理,是被 exchange 直接丢弃还是由其发回给 producer (Basic.Return+Content-Header+Content-Body)。
3.mandatory 和 Publisher confirm 机制的区别?
Publisher confirm 机制是用来确认 message 的可靠投递,mandatory 参数是用来确保在 queue 不存在的情况下,message 不会被 blackholed 。
queue 存在时,开启 mandatory 的情况:
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
|
[warn] evsignal_init: socketpair: No error
drive_machine: [conn_init] ---
in
TCP 3-way connecting!
drive_machine: [conn_connecting] --- connection timeout 1
time
on socket(6040)
drive_machine: [conn_connected] --- connected on socket(6040)
6040: conn_state change connected ==> snd_protocol_header
--> Send Protocol.Header!
6040: conn_state change snd_protocol_header ==> rcv_connection_start_method
<-- Recv Connection.Start Method frame!
6040: conn_state change rcv_connection_start_method ==> snd_connection_start_rsp_method
--> Send Connection.Start-Ok Method frame!
6040: conn_state change snd_connection_start_rsp_method ==> rcv_connection_tune_method
drive_machine: wait
for
Connection.Tune method another 10 seconds!!
<-- Recv Connection.Tune Method frame!
6040: conn_state change rcv_connection_tune_method ==> snd_connection_tune_rsp_method
--> Send Connection.Tune-Ok Method frame!
6040: conn_state change snd_connection_tune_rsp_method ==> snd_connection_open_method
--> Send Connection.Open Method frame!
6040: conn_state change snd_connection_open_method ==> rcv_connection_open_rsp_method
<-- Recv Connection.Open-Ok Method frame!
6040: conn_state change rcv_connection_open_rsp_method ==> snd_channel_open_method
--> Send Channel.Open Method frame!
6040: conn_state change snd_channel_open_method ==> rcv_channel_open_rsp_method
drive_machine: wait
for
Channel.Open-Ok method another 10 seconds!!
<-- Recv Channel.Open-Ok Method frame!
6040: conn_state change rcv_channel_open_rsp_method ==> idle
drive_machine: [conn_idle] --- [PRODUCER]: Find something to send!
6040: conn_state change idle ==> snd_basic_publish_method
--> Send Basic.Publish Method frame!
6040: conn_state change snd_basic_publish_method ==> snd_basic_content_header
--> Send Content-Header frame!
6040: conn_state change snd_basic_content_header ==> snd_basic_content_body
--> Send Content-Body frame!
6040: conn_state change snd_basic_content_body ==> idle
drive_machine: [conn_idle] --- [PRODUCER]: Find nothing to send! wait
for
another 10 seconds
drive_machine: [conn_idle] --- [PRODUCER]: Find nothing to send! wait
for
another 10 seconds
|
queue 不存在时,开启 mandatory 的情况:
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
39
40
41
42
43
|
[warn] evsignal_init: socketpair: No error
drive_machine: [conn_init] ---
in
TCP 3-way connecting!
drive_machine: [conn_connecting] --- connection timeout 1
time
on socket(8088)
drive_machine: [conn_connected] --- connected on socket(8088)
8088: conn_state change connected ==> snd_protocol_header
--> Send Protocol.Header!
8088: conn_state change snd_protocol_header ==> rcv_connection_start_method
drive_machine: wait
for
Connection.Start method another 10 seconds!!
<-- Recv Connection.Start Method frame!
8088: conn_state change rcv_connection_start_method ==> snd_connection_start_rsp_method
--> Send Connection.Start-Ok Method frame!
8088: conn_state change snd_connection_start_rsp_method ==> rcv_connection_tune_method
<-- Recv Connection.Tune Method frame!
8088: conn_state change rcv_connection_tune_method ==> snd_connection_tune_rsp_method
--> Send Connection.Tune-Ok Method frame!
8088: conn_state change snd_connection_tune_rsp_method ==> snd_connection_open_method
--> Send Connection.Open Method frame!
8088: conn_state change snd_connection_open_method ==> rcv_connection_open_rsp_method
<-- Recv Connection.Open-Ok Method frame!
need to code something!
8088: conn_state change rcv_connection_open_rsp_method ==> snd_channel_open_method
--> Send Channel.Open Method frame!
8088: conn_state change snd_channel_open_method ==> rcv_channel_open_rsp_method
drive_machine: wait
for
Channel.Open-Ok method another 10 seconds!!
<-- Recv Channel.Open-Ok Method frame!
need to code something!
8088: conn_state change rcv_channel_open_rsp_method ==> idle
drive_machine: [conn_idle] --- [PRODUCER]: Find something to send!
8088: conn_state change idle ==> snd_basic_publish_method
--> Send Basic.Publish Method frame!
8088: conn_state change snd_basic_publish_method ==> snd_basic_content_header
--> Send Content-Header frame!
8088: conn_state change snd_basic_content_header ==> snd_basic_content_body
--> Send Content-Body frame!
8088: conn_state change snd_basic_content_body ==> rcv_basic_return_method
<-- Recv Basic.Return Method frame!
### reply_code: 312, reply_text: NO_ROUTE, exchange=amq.direct, routing_key=test1
8088: conn_state change rcv_basic_return_method ==> idle
drive_machine: [conn_idle] --- [PRODUCER]: Find nothing to send! wait
for
another 10 seconds
drive_machine: [conn_idle] --- [PRODUCER]: Find nothing to send! wait
for
another 10 seconds
|
该图显示了在 Basic.Publish 中设置 mandatory 为 true 。
该图中显示了当 queue 不存在时,服务器返回 Basic.Return + Content.Header + Content.Body 的内容。
下图为正常情况和异常情况。