想象一下,每個用戶都有自己的隊列。當用戶離線時,郵件會被放入隊列中,當他們重新連接時,郵件會收到所有這些郵件。RabbitMQ:如果消費者永遠消失,請刪除一個隊列?
但是,如果客戶端離開並永不回來(停止使用該服務)會怎麼樣?如果消息在一段時間內沒有被消費,RabbitMQ是否有辦法刪除一個隊列?消息可能會進入,但它們不會熄滅,因爲客戶端不再處於活動狀態。我怎樣才能用amqp.node插件處理這個問題?
想象一下,每個用戶都有自己的隊列。當用戶離線時,郵件會被放入隊列中,當他們重新連接時,郵件會收到所有這些郵件。RabbitMQ:如果消費者永遠消失,請刪除一個隊列?
但是,如果客戶端離開並永不回來(停止使用該服務)會怎麼樣?如果消息在一段時間內沒有被消費,RabbitMQ是否有辦法刪除一個隊列?消息可能會進入,但它們不會熄滅,因爲客戶端不再處於活動狀態。我怎樣才能用amqp.node插件處理這個問題?
試想每個用戶都有自己的隊列。當用戶離線時,郵件會被放入隊列中,當他們重新連接時,郵件會收到所有這些郵件。
這是一個普遍的想法,但one with unfortunate consequences, that you should avoid。
,因爲我是掛在文章中寫道:
您可能會解決此通過在每個用戶的隊列。您 可能會設置您的代碼,以便Web服務器僅在用戶登錄且可用時爲用戶訂閱 隊列。
這並不能解決問題。
現在,您已經有30000條消息分佈在1000個隊列中 - 其本身就是一個不好的 情況。這需要RabbitMQ在隊列中保留隊列和消息。當所有1,000個用戶同時登錄到您的系統時會發生什麼?現在您的Web服務器有1000 隊列訂閱來處理。
當然,你可能會爭辯說,你不會有那麼多的用戶。但情況變得更糟。在你的情況下,你將無法自動地以你想要的方式刪除隊列。
您可以設置一個隊列,在所有使用者斷開連接後自動刪除。但保持隊列將需要每個用戶隊列的消費者,消費者在該用戶存在時連接到該隊列。如果應用程序崩潰,則隊列及其所有消息都將消失。
TTL只會做你想要的一部分。它會在隊列中放置一條消息並在該超時之後刪除該消息...但它不會刪除該隊列。
最終,你不想用RabbitMQ做到這一點。
再次再回到原來的情況下,當 用戶不在線,你不能立即將消息發送到他們應該怎麼做?
將消息存儲在數據庫中。
將一個字段添加到數據庫記錄中,該字段說明此消息的來源爲 。當用戶稍後重新連接時,請查詢數據庫以獲取該用戶此時需要查看併發送的任何 消息。
全過程上面開始,然後變成這樣:
- 用戶的瀏覽器連接到SignalR/Socket.io /子彈頭/ WebSockets的網絡上服務器
- Web服務器檢查隊列的過程中所發生的更新長 運行的進程
- 當如果 用戶爲LO一個登錄用戶進來
- 消息gged中,廣播通過WebSocket的消息給 用戶
- 如果用戶沒有登錄,存儲信息的數據庫
- 當用戶再次登錄,查詢數據庫,並把所有的等待 消息
這就是你會做一個消息隊列 的想法來之前在玩,對吧?它應該是你現在要做的事,即你有一個消息隊列。
這似乎是可能的,但我沒有嘗試過自己。請參閱:在隊列TTL
https://www.rabbitmq.com/ttl.html
看一路下跌底部。 「這控制了隊列在被自動刪除之前可以不用的時間。」
要查看示例用法,本次測試的節點AMQP代碼庫可能是鼓舞人心:
這並不回答我的問題,但它回答了「我該如何處理我想要做的事情?」的問題。所以我接受了它。你是對的!我最初使用數據庫來存儲這些消息,但發現RabbitMQ,並認爲它幾乎是一個錯誤的「消息數據庫」。謝謝你打開我的眼睛!儘管問題很快......您對於存儲這些信息的數據庫的建議是什麼? –
是的,我希望回答這個意圖,而不是真正的問題會更有價值:D至於什麼數據庫使用?你通常使用什麼?你的應用/系統中已經有了什麼數據庫?堅持你所知道的數據庫。 –
我想我們將使用Redis列表。 O(1)插入和「流行」功能非常棒。我正在考慮彈出redis列表中的值並通過網絡套接字發送消息。我正在尋找「全部彈出」功能,但「彈出時不返回空」是另一種選擇。 –