RabbitMQ - work queue 工做模式

前言

上一篇 RabbitMQ 入門 對 RabbitMQ 作了入門瞭解並介紹了他的一種工做模式-簡單模式。本篇來學習一下 RabbitMQ 的第二種工做模式 - work queue。學習


worke queue介紹

先來看官網的一張圖, 如圖所示,咱們能夠看到,與上一篇介紹的簡單模式不一樣之處在於,這裏存在多個消費者。多個消費者如何處理隊列中的消息,咱們後面會說道。fetch


work queue 的做用

work queue 的思想 是避免當即去執行一些耗時任務,而且一直等待任務完成, 而是分發耗時的任務給多個worker, 也就是生產者將消息發送到隊列,而後消費者能夠輪流從隊列中讀取消息。spa


RabbitMQ 的一些特性

接下來介紹 RabbitMQ 使用過程當中容易遇到的問題,以及解決辦法。.net

消息確認機制

消息確認機制做用是當某個客戶端忽然掛掉了,消息不會丟失。code

處理一個消息須要幾秒鐘,你可能想知道,當一個消費者正在處理一個很耗時的任務時,掛掉了會發生什麼。若是不作特殊處理,當mq把消息傳遞給消費者時, 這個消息就會被當即刪除。因此此時若是你殺掉一個消費者時,這個消費者正在處理以及未處理的消息都會丟失。面對以上的狀況,咱們一般想把消息交給其餘消費者去處理。這個時候咱們就可使用rabbitmq的消息確認機制-消費者收到消息後,會去通知mq我已經收到消息了,而後你能夠把消息刪除了。若是一個消費者掛掉了,而且沒有發送 ack 給生產者,此時生產者就會當即把消息從新發送到另外一個還活着的消費者手中。消息確認機制默認是打開的,(autoAck=false)channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); 若是忘記 basicAck,會帶來很嚴重的後果,若是你的客戶端退出,消息會從新發送,最終RabbitMQ 會吃掉不少內存。blog

消息持久化

消息持久化的做用是當RabbitMQ Server 掛掉了,消息不會丟失rabbitmq

當mq 退出或崩掉的時候,它就會「忘記」那些隊列和消息,除非你告訴他。解決這種問題的辦法就是將隊列 和 消息本地持久化。隊列

1. 隊列持久化

在消費者和生產者客戶端同時聲明
channel.queueDeclare("hello", durable, false, false, null);// durable = true;
這裏須要注意的是: RabbitMQ 是不容許建立一個已存在的隊列的,即便你使用不一樣參數。

2. 消息持久化

channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

注意: 即便作了消息持久化,也不能徹底保證消息丟失,在RabbitMQ 接收到消息還沒保存的這段時間,消息仍有可能會丟失。所以消息持久化僅僅能知足一些簡單的任務隊列。若是須要更加健壯的機制,須要學習下 Publisher Confirms內存

Fair dispatch

若是咱們有奇數個 "重量級" 的消息,和偶數個 "輕量級" 的消息, 那麼在咱們的程序運行中,會出現一個 worker 老是很忙的狀況, 由於它不停地在處理 那些 "重量級" 的消息。可是RabbitMQ 殊不知道誰輕鬆誰不輕鬆。get

如何預防?

`channel.basicQos(prefetchCount);// prefetchCount = 1;`

這行代碼的做用就是告訴 RabbitMQ 不要在某一時刻,發送多個消息給worker, 等worker 確認完以後,再發送

相關文章
相關標籤/搜索