1. 問題描述與解決方案
- 問題: 查看業務日志發現, 生產者和消費者都被"卡死", 沒有看到錯誤日志. 查看 RabbitMQ 控制台發現 connection 都被 blocked. 同時看到磁盤空間警告.
- 解決方案: 修改配置文件把 disk_free_limit.absolute 從 20 GB 降低到 10GB, 重啟 RabbitMQ, 解決問題.
2. 原因探究
在運行期間, RabbitMQ 節點將根據工作負載消耗不同數量的內存和磁盤空間. 當使用率激增時, 內存和可用磁盤空間都可能達到潛在的危險水平. 比如內存的不斷消
耗, 可能導致節點被“操作系統的內存不足進程終止機制”殺掉.
為了降低這些情況的可能性, RabbitMQ 具有兩個可配置的資源水位警戒線. 當觸發警戒線時, RabbitMQ將阻止發布消息的 connection.
- 當內存使用量超過配置的警戒線時.
- 當可用磁盤空間降到配置的警戒線以下時.
通俗點理解, 內存觀察的是水位線上升, 磁盤觀察的是水位線下降.
2.1 Client Notifications
Modern client libraries support connection.blocked notification (a protocol extension), so
applications can monitor when they are blocked.
2.2 集群中的警報
在 rabbitmq 集群模式下, 內存和磁盤的告警是整個集群范圍內的, 如果一個節點出現了告警, 則整個集群的所有節點都會阻塞 connection. 目的是阻止生產者, 消費
者可以繼續消費而不受影響. 雖然協議允許生產者和消費者在單個 connection 的同一個 channel 或不同 channel 上進行操作, 但是這個邏輯是不完美的. 在實踐上建
議僅將單個 connection 用於生產或者消費.
2.3 Effects on Data Safety
When an alarm is in effect, publishing connections will be blocked by TCP back pressure. In practice this means that publish operations will
eventually time out of fail outright. Application developers must be prepared to handle such failures and use publisher confirms to keep
track of what messages have been successfully handled and processed by RabbitMQ.
** It is strongly recommended that OS swap or page files are enabled. **
2.4 配置內存閾值
- 百分比配置
0.4 指內存的40%.
# new style config format, recommended
vm_memory_high_watermark.relative = 0.4
- 固定值配置
vm_memory_high_watermark.absolute = 2GB
2.5 配置磁盤可用空間限制
- 內存大小 * 1.0
disk_free_limit.relative = 1.0
- 固定值配置
disk_free_limit.absolute = 1GB
3. 總結
RabbitMQ connection 的創建, 消費者與生產者要分開, 如果你使用 SpringAMQP 的話, 它已經提供了這樣的功能:
// To avoid deadlocked connections, it is generally recommended to use a separate connection for publishers
// and consumers (except when a publisher is participating in a consumer transaction).
rabbitTemplate.setUsePublisherConnection(true);
有問題歡迎留言交流。
技術交流群:282575808
點擊鏈接加入群聊【互聯網技術交流群】
