房地產(chǎn)開發(fā)公司網(wǎng)站源代碼 墨綠色風格最新的疫情情況
在默認情況下,RabbitMQ會將接收到的信息保存在內(nèi)存中以降低消息收發(fā)的延遲。但在某些特殊情況下,這會導致消息積壓,比如:
- 消費者宕機或出現(xiàn)網(wǎng)絡故障
- 消息發(fā)送量激增,超過了消費者處理速度
- 消費者處理業(yè)務發(fā)生阻塞
一旦出現(xiàn)消息堆積問題,RabbitMQ的內(nèi)存占用就會越來越高,直到觸發(fā)內(nèi)存預警上限。此時RabbitMQ會將內(nèi)存消息刷到磁盤上,這個行為成為PageOut
. PageOut
會耗費一段時間,并且會阻塞隊列進程。因此在這個過程中RabbitMQ不會再處理新的消息,生產(chǎn)者的所有請求都會被阻塞。
為了解決這個問題,從RabbitMQ的3.6.0版本開始,就增加了Lazy Queues的模式,也就是惰性隊列。惰性隊列的特征如下:
- 接收到消息后直接存入磁盤而非內(nèi)存
- 消費者要消費消息時才會從磁盤中讀取并加載到內(nèi)存(也就是懶加載)
- 支持數(shù)百萬條的消息存儲
而在3.12版本之后,LazyQueue已經(jīng)成為所有隊列的默認格式。因此官方推薦升級MQ為3.12版本或者所有隊列都設置為LazyQueue模式
1.控制臺配置Lazy模式
在添加隊列的時候,添加x-queue-mod=lazy
參數(shù)即可設置隊列為Lazy模式:
2.代碼配置Lazy模式
在利用SpringAMQP聲明隊列的時候,添加x-queue-mod=lazy
參數(shù)也可設置隊列為Lazy模式:
@Beanpublic
Queue lazyQueue(){ return QueueBuilder.durable("lazy.queue").lazy() // 開啟Lazy模式.build();}
這里是通過QueueBuilder
的lazy()
函數(shù)配置Lazy模式,底層源碼如下:
當然,我們也可以基于注解來聲明隊列并設置為Lazy模式:
@RabbitListener(queuesToDeclare = @Queue(name = "lazy.queue",durable = "true",arguments = @Argument(name = "x-queue-mode", value = "lazy")))public void listenLazyQueue(String msg){log.info("接收到 lazy.queue的消息:{}", msg);}
3.更新已有隊列為lazy模式
對于已經(jīng)存在的隊列,也可以配置為lazy模式,但是要通過設置policy實現(xiàn)。
可以基于命令行設置policy:
rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues
命令解讀:
rabbitmqctl
:RabbitMQ的命令行工具set_policy
:添加一個策略Lazy
:策略名稱,可以自定義"^lazy-queue$"
:用正則表達式匹配隊列的名字'{"queue-mode":"lazy"}'
:設置隊列模式為lazy模式--apply-to queues
:策略的作用對象,是所有的隊列
當然,也可以在控制臺配置policy,進入在控制臺的Admin
頁面,點擊Policies
,即可添加配置: