消息隊列選擇:RabbitMQ & Redisgit
RabbitMQ是一個由erlang開發的AMQP(Advanced Message Queue )的開源實現的產品,RabbitMQ是一個消息代理,從「生產者」接收消息並傳遞消息至「消費者」,期間可根據規則路由、緩存、持久化消息。「生產者」也即message發送者如下簡稱P,相對應的「消費者」乃message接收者如下簡稱C,message經過queue由P到C,queue存在於RabbitMQ,可存儲儘量多的message,多個P可向同一queue發送message,多個C可從同一個queue接收message
RabbitMQ架構:github
組件:golang
Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。數據庫
Redis 與其餘 key - value 緩存產品有如下三個特色:ubuntu
首先Redis的設計是用來作緩存的,可是因爲它自身的某種特性使得他能夠用來作消息隊列(Redis的List數據結構比較適合作MQ)。它有幾個阻塞式的API可使用,正是這些阻塞式的API讓他有作消息隊列的能力。 另外作消息隊列的其餘特性,例如FIFO也很容易實現,只須要一個list對象從頭取數據,從尾部塞數據便可實現。 Redis能作消息隊列得益於它的list對象blpop brpop接口以及Pub/Sub(發佈/訂閱)的某些接口。他們都是阻塞版的,因此能夠用來作消息隊列。緩存
RabbitMQ和Redis均可以作隊列,可是他們仍是有區別的。好比,Redis的消息隊列,若是在從隊列pop出去的時候,worker處理失敗的話,數據不會回到隊列中,須要從業務中手動把失敗的處理數據push到隊列中;而RabbitMQ能夠自動處理失敗的worker使數據不丟失;RabbitMQ還能夠保證數據在傳輸過程當中持久化,在通道和隊列中的數據能夠設置爲持久化。首先Redis嚴格來講並非消息隊列,它是一個內存數據庫,不過由於其某些特性適合用來充當隊列,因此也多被用於作簡單的mq, Redis之父卻是開發了個真正的消息隊列disque,有興趣能夠看看。數據結構
相比起Redis,RabbitMQ有更加完善的MQ機制,這裏咱們僅討論消息的durable(持久性),後續一系列其餘機制有時間再交流。架構
RabbitMQ有一個消息確認機制來保證消息的不丟失:客戶端從隊列中取出消息以後,可能須要一段時間才能處理完成,若是在這個過程當中,客戶端出錯了,異常退出了,而數據尚未處理完成,那麼很是不幸,這段數據就丟失了,由於RabbitMQ默認會把此消息標記爲已完成,而後從隊列中移除,消息確認是客戶端從RabbitMQ中取出消息,並處理完成以後,會發送一個ack告訴RabbitMQ,消息處理完成,當RabbitMQ收到客戶端的獲取消息請求以後,或標記爲處理中,當再次收到ack以後,纔會標記爲已完成,而後從隊列中刪除。當RabbitMQ檢測到客戶端和本身斷開連接以後,還沒收到ack,則會從新將消息放回消息隊列,交給下一個客戶端處理,保證消息不丟失,也就是說,RabbitMQ給了客戶端足夠長的時間來作數據處理。性能
no-ack = False,若是消費者遇到狀況(its channel is closed, connection is closed, or TCP connection is lost)掛掉了,那麼,RabbitMQ會從新將該任務添加到隊列中。spa
發送ack則被認爲是正常消費message的consumer,則RabbitMQ會把message從隊列中移除,此時再看隊列中已經沒有消息。
關於RabbitMQ的其餘features,如 Publish/Subscribe、Routing、Topics和RPC等,有興趣能夠Google。除了RabbitMQ除了Python的實踐外,也可考慮其餘語言的實踐,這裏提供另一個語言golang的選擇,可參考Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳實踐,這個文章講的很是詳盡,實踐意義比較具備參考價值,有興趣能夠閱覽一番。