什麼情況下異步操作使用消息隊列而不是多線程

Redis提供了兩種方式來作消息隊列。 
一個是使用生產者消費模式模式, 另一個就是發佈訂閱者模式。 
前者會讓一個或者多個客戶端監聽消息隊列,一旦消息到達,消費者馬上消費,誰先搶到算誰的,如果隊列裏沒有消息,則消費者繼續監聽;’後者也是一個或多個客戶端訂閱消息頻道,只要發佈者發佈消息,所有訂閱者都能收到消息,訂閱者都是平等的。

一、異步處理選擇

1.消息隊列和多線程兩者並不衝突,多線程可以作爲隊列的生產者和消費者。
使用外部的消息隊列時,第一是可以提高應用的穩定性,當程序fail後,寫入外部消息隊列的數據依舊是保存的,如果使用兩步commit的隊列的話,可以更加提高這個項目。

2.用線程的話,會佔用主服務器資源,消息隊列的話,可以放到其他機器上運行,讓主服務器儘量多的服務其他請求。

3.解耦更充分,架構更合理
多線程是在編程語言層面解決問題
消息隊列是在架構層面解決問題
我認爲架構層面解決問題是“覺悟比較高的方式“,理想情況下應該限制語言層面濫用多線程,能不用就不用。

4.用線程池ExecutorService異步處理:我理解ExecutorService其實也是內部使用了隊列(如LinkedBlockingQueue),所以從設計上,其實和使用中間件的消息隊列是差不多一致的。只是這裏應用服務器既充當生產者又充當消費者,也是消息隊列中間件的實現者。這種應該適合非分佈式的架構,比如簡單的只有一臺服務器。

使用消息隊列:消息隊列(指activeMQ,rabbitMQ,kafaKa,Redis等)因爲一般都是中間件,部署在其他機器,需要一定的網絡消耗。

本着解耦的目的,使用後者更合理,因爲應用服務器一般內存也不會太多,隊列長度不易太長。讓應用服務器只處理邏輯比較合理。適合分佈式架構。
 

二、將redis發佈訂閱模式用做消息隊列和rabbitmq的區別

1、可靠性

redis :沒有相應的機制保證消息的可靠消費,如果發佈者發佈一條消息,而沒有對應的訂閱者的話,這條消息將丟失,不會存在內存中;

rabbitmq:具有消息消費確認機制,如果發佈一條消息,還沒有消費者消費該隊列,那麼這條消息將一直存放在隊列中,直到有消費者消費了該條消息,以此可以保證消息的可靠消費.

 2、實時性

redis:實時性高,redis作爲高效的緩存服務器,所有數據都存在在服務器中,所以它具有更高的實時性。

3、消費者負載均衡:

rabbitmq隊列可以被多個消費者同時監控消費,但是每一條消息只能被消費一次,由於rabbitmq的消費確認機制,因此它能夠根據消費者的消費能力而調整它的負載;

redis發佈訂閱模式,一個隊列可以被多個消費者同時訂閱,當有消息到達時,會將該消息依次發送給每個訂閱者;

4、持久性

redis:redis的持久化是針對於整個redis緩存的內容,它有RDB和AOF兩種持久化方式(redis持久化方式,後續更新),可以將整個redis實例持久化到磁盤,以此來做數據備份,防止異常情況下導致數據丟失。

rabbitmq:隊列,消息都可以選擇性持久化,持久化粒度更小,更靈活;

 5、隊列監控

rabbitmq實現了後臺監控平臺,可以在該平臺上看到所有創建的隊列的詳細情況,良好的後臺管理平臺可以方便我們使用;

redis沒有所謂的監控平臺。

6、出入隊性能

對於RabbitMQ和Redis的入隊和出隊操作,各執行100萬次,每10萬次記錄一次執行時間。
測試數據分爲128Bytes、512Bytes、1K和10K四個不同大小的數據。
實驗數據表明:
入隊時,當數據比較小時Redis的性能要高於RabbitMQ,而如果數據大小超過了10K,Redis則慢的無法忍受;
出隊時,無論數據大小,Redis都表現出非常好的性能,而RabbitMQ的出隊性能則遠低於Redis。

 

三、總結

redis:       輕量級,低延遲,高併發,低可靠性;

rabbitmq:重量級,高可靠,異步,不保證實時;

rabbitmq是一個專門的AMQP協議隊列,他的優勢就在於提供可靠的隊列服務,並且可做到異步,而redis主要是用於緩存的,redis的發佈訂閱模塊,可用於實現及時性,且可靠性低的功能。

所以項目中所採用的Redis可能只是用於一個輕量級的應用,只是用於簡單的發短信,郵件等通知,如果業務要進一步的擴展,如果需要消息隊列的話,可能還需要用到專用的那些重量級的消息中間件比如rabbitmq等,他們的高可靠,負載均衡這些特性都是Redis所沒有的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章