tutorial:
這裡解釋接收訊息端關於 acknowledge和prefetch的設定問題
這裡有兩段**,sender,負責傳送100條訊息; recv,負責接收訊息,每接收到一條訊息sleep 1 秒。
1 channel.queuedeclare(queue_name, false, false, false, null);2先展示乙個基礎版本的recv。3 system.out.println(" [*] waiting for messages. to exit press ctrl+c");
45 consumer consumer = new
defaultconsumer(channel) catch
(exception e)
16//
channel.basicack(envelope.getdeliverytag(), false);
1718}19
};20 channel.basicconsume(queue_name, true, consumer);
執行這段**遇到兩個費解的現象
1. 先啟動sender產生100條訊息,後啟動兩個recv,發現所有訊息都被第乙個啟動的recv接收了,第二個recv沒有接收到任何訊息。但如果先兩個recv,再啟動sender,那麼兩個recv是平均分配訊息的。
2. 先啟動sender,啟動第乙個recv,處理10條訊息,關掉recv,再啟動第二個recv,第二個recv沒有訊息。11~100條訊息丟失了。
為了說明上面的問題,我們先描述一下乙個訊息在rmq server端的狀態
在server端,訊息進入queue後,首先是ready狀態。如果有recv 消費這條訊息,那麼訊息進入 unack 狀態,當recv ack這條訊息後,server端將刪除訊息。
現象1的解釋:
先啟動sender,server端有100個ready 訊息。啟動recv1,雖然recv1還沒有來得及處理這些訊息,但recv1 接收了100個訊息。在server端100個訊息都進入unack狀態。因為我們設定的ack方式是autoack, line 20
因此所有訊息立刻就從server端刪除了。當我再啟動recv2時,佇列已經沒有訊息了,所以recv2沒有接收到任何訊息。反過來,先啟動兩個recv,sender生產訊息的時候,server會按round robbin方式分配訊息,因此兩個recv各接收50條訊息
現象2的解釋:
因為訊息都已經傳送給了recv1,server端收到了ack,刪除了訊息,系統中只有recv1快取了訊息,如果關掉recv1,所有訊息都會丟失。recv2無法拿到recv1未處理的訊息。
下面我們看看改進版本。變化在於
1 channel.queuedeclare(queue_name, false, false, false, null);2可以發現現象1 依舊,但現象2 不同了。我們可以通過命令檢視server端的狀態3 system.out.println(" [*] waiting for messages. to exit press ctrl+c");
45 consumer consumer = new
defaultconsumer(channel) catch
(exception e)
16 channel.basicack(envelope.getdeliverytag(), false
);1718}
19};
20 channel.basicconsume(queue_name, false, consumer);
rabbitmqctl list_queues name messages_unacknowledged messages_ready啟動sender後 unack=0,ready=100
啟動recv1 後 unack=100, ready=0,所有訊息都給了recv1
等recv1 處理幾條訊息後 unack=89, ready=0,recv1處理並ack了11條訊息,
關閉recv1 後 unack=0, ready=85,未ack的訊息都回到ready狀態
啟動recv2,unack=89, ready =0,所有訊息都轉給了recv2.
如果訊息量很大,那麼快取訊息就可能吃掉recv的所有記憶體導致系統崩潰。因此我們開啟 line2。這樣recv在ack乙個訊息後才會領取下乙個訊息。再來看看按照上面流程queue裡訊息的狀態
啟動sender後 unack=0,ready=100
啟動recv1 後,unack=1, ready=99
啟動recv2後,unack=2, ready=95
在訊息處理完前,unack都是2,recv1和recv2 各持有乙個訊息
RabbitMQ訊息的處理
訊息的確認,是指生產者投遞訊息後,如果broker收到訊息,則會給我們生產這乙個應答。生產者進行接收應答,用來確定這條訊息是否正常的傳送到broker,這種方式也是訊息的可靠性投遞的核心保障。確認機制流程圖 如何實現confirm確認訊息?第一步 在channel上開啟確認模式 channel.co...
RabbitMQ 訊息廣播
rabbitmq訊息模型的核心理念是 發布者 producer 不會直接傳送任何訊息給佇列。事實上,發布者 producer 甚至不知道訊息是否已經被投遞到佇列。發布者 producer 只需要把訊息傳送給乙個交換機 exchange 交換機非常簡單,它一邊從發布者方接收訊息,一邊把訊息推送到佇列。...
RabbitMQ 廣播訊息
定義 廣播訊息是指生產者產生的訊息將分發給所有訂閱這個訊息的消費者,而普通的模式是 一批訊息可以被多個人共同消費,如consumer1可能消費1,3,5記錄,而consumer2可能消費的是2,4,6這種模組就是共同消費模組 而今天說的是廣播訊息,它是指一些訊息同時被推送到多個訂閱者,而這些訂閱者收...