這一篇文章讓我們看看在消息系統中可能發生的各種錯誤的情況下,看下EasyNetQ如何處理它們。
訂閱服務掛了
當你寫了一個windows 服務,用來訂閱一個NewCustomerMessage消息。
如果這個服務失敗時會發生什么呢?為了效率,EasyNetQ為訂閱功能實現了一個基於內存的內部使用的隊列。消息通過網絡從RabbitMQ中接收到后,會把消息放到這個內存隊列中。一個訂閱者線程從這個內存隊列拿走消息后,回調自己提供的消息處理代碼。一旦這個回調完成后,EasyNetQ會發送'Ack'給RabbitMQ。沒有收到'Ack'前,這個消息不會從RabbitMQ消息隊列中被刪除。如果你的服務在處理這個消息時掛掉了,這個消息(所有的消息都在EasyNetQ內存隊列中)仍將呆在RabbitMQ隊列中。直到你的服務再次連接上后,這些消息將會再次被發送。
我的訂閱者消費消息的速度比消息發布速度慢
EasyNetQ利用了RabbitMQ服務的特性,設置prefetch-count值為一個比較可用的值(當前是50).這意味着,將最多不會超過50條消息在消費者的內存隊列中。這樣會防止在你的正在訂閱的應用發生內存超出異常。一旦未Ack消息數累積到這個值后,RabbitMQ將停止發送消息,只是保留這些消息在EasyNetQ的內存隊列中。當然,最終這個隊列將會吃掉你的RabbitMQ服務器上的所有磁盤空間。你應該在這個地方做下監控,確保在發生這種情況發生前你能夠得到警報。
在我的訂閱者和RabbitMQ代理之間發生網絡故障
如前面文章用EasyNetQ連接RabbitMQ所述,EasyNetQ實現了一個延遲連接策略。這個策略假設這個代理不會總是可用的。當你第一次通過使用RabbitHutch.CreateBus連接到這個代理時,EasyNetQ開啟一個連接,不斷循環嘗試去連接代理,如果你指定的連接字符串地址的代理沒有處於可用狀態,你會從消息信息日志中看到'Trying to Connect'。訂閱者能夠使用bus.Subscribe方法去訂閱,即使當這個代理不可用時。這個訂閱的細節會被EasyNetQ緩存。 當代理恢復可用時,這個正在不斷循環嘗試連接將會成功連接到代理,並且所有緩存的訂閱一同恢復。
同樣,當EasyNetQ和代理連接中斷時,它將返回到循環連接,你在日志中看'Trying to Connect'信息。一旦連接重新建立,被緩存的訂閱者將再次被建立。最后結論就是,在正在運行環境中,無論在網絡斷開時,或是你需要在被你的RabbitMQ代理拒絕時,你能夠保留你的訂閱者。
當消費一個消息時,訂閱回調拋出異常
如果你的訂閱回調拋出異常,EasyNetQ將會拿到這個正在被消費的消息,包裝這個消息到一個指定錯誤消息中。這個錯誤消息將會被發布到EasyNetQ的錯誤隊列(名字是EasyNetQ_Default_Error_Queue)。你應該監控這個錯誤隊列中的消息。這個錯誤消息包括所有必要的信息,例如需要重新發布的原始消息,以及異常的類型,異常信息和堆棧信息。你可能使用EasyNetQ.Hosepipe工具重新發布錯誤信息。參考下一篇文章EasyNetQ.Hosepipe
英文地址:https://github.com/EasyNetQ/EasyNetQ/wiki/Error-Conditions
本文地址:http://www.cnblogs.com/HuangLiang/p/EasyNetQ-Error-Conditions.html
我的微信訂閱號:open_dotNET