【原创】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 的情况:
[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 的情况:
[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 。
【原创】RabbitMQ 之 mandatory_第1张图片

该图中显示了当 queue 不存在时,服务器返回 Basic.Return + Content.Header + Content.Body 的内容。
【原创】RabbitMQ 之 mandatory_第2张图片

下图为正常情况和异常情况。
【原创】RabbitMQ 之 mandatory_第3张图片


你可能感兴趣的:(rabbitmq,mandatory)