非集群下,簡單的說:
- 如果是excl,則設置durability沒有意義,因為不管服務器掛了還是客戶端主動/被動斷開了,隊列都會自動刪除。
- auto-delete,其實可簡單的認為是同理,即使非excl,則無論是服務器掛了還是全部消費者斷開了,隊列都會刪除。
集群下:
這還真得測試如下:
1、A服務器掛了,客戶端連接從A自動切換到B之后(即使配置了多個,任何時候MQ仍然只是連接到一個),MQ服務器是否認為仍然是原來的消費者?從理論上來說,應該是要認為相同的,不然就失去了集群的意義。
2、服務不是在客戶端設置多個地址,而是通過haproxy進來的(不過一般大規模來說,應該使用TCP負載均衡器,小規模可能運維考慮不用),此時又是什么樣的含義。
關于可靠傳輸,發布、訂閱端發送后沒有收到ack/confirm時的業務狀態一致性判斷問題,通常來說靠協議自身去實現100%可靠性是很難的(總要有補償機制兜底),主要要應用層去如何設計以最小化開發/維護/運行時成本的處理。
ACK:消費者->RabbitMQ的消息處理確認
confirm:RabbitMQ->發布者的消息收到確認(AMQP標準里面用事務,太重量級)
ACK+confirm+persistent是確保消息可信到達唯一條件,即使如此,仍然有可能存在鏈路上的問題。如下:
publish,未收到confirm客戶端掛了,服務器已成 業務可重復執行(尤其是如果生產者是整個鏈路的中間環節)
publish,未收到confirm服務器掛了,服務器已成 業務可重復執行(尤其是如果生產者是整個鏈路的中間環節)
publish,未收到confirm客戶端掛了,服務器未成 無需處理,理論上不可能發生
publish,未收到confirm服務器掛了,服務器未成 客戶端處理異常
consume,未收到ack客戶端掛了,客戶端已成 業務可重復執行(尤其是如果消費者是整個鏈路的中間環節)
consume,未收到ack服務器掛了,客戶端已成 業務可重復執行(尤其是如果消費者是整個鏈路的中間環節)
consume,未收到ack客戶端掛了,客戶端未成 無需處理,服務端自動重發
consume,未收到ack服務器掛了,客戶端未成 無需處理,理論上不可能發生
同時要考慮集群下是否完全一致。