面向后端開發(fā)者的5個隊列系統(tǒng)
隊列是一種數(shù)據(jù)結(jié)構(gòu),它可以模仿我們在真實世界的隊列。例如,如果你去排隊購票,你必須站在隊列的最后,而隊列開頭的人將優(yōu)先購買。這就是我們所說的“先到先得”的現(xiàn)象。在編程中,可以編寫任務存儲在隊列中的程序,并以先到先得的方式逐個處理它們。而隊列本身不進行任何實際處理,它只是臨時存儲的各種任務。我們對隊列系統(tǒng)的主要需求是因為后臺處理,并行執(zhí)行和故障恢復。比如:

后臺處理
假設你正在運行電子商務的營銷,那么時間就至關(guān)重要了。如果應用已構(gòu)建,以便在客戶完成付款之前觸發(fā)確認電子郵件,并顯示回復頁面。如果你連接的郵件服務器已關(guān)閉,則網(wǎng)頁無法打開,而影響用戶體驗。想象一下當獲得的大量支持請求的情況下,最好將電子郵件發(fā)送任務推送到作業(yè)隊列。
并行執(zhí)行
許多開發(fā)人員,特別是那些主要編寫簡單,流量較低的應用的開發(fā)人員,習慣于使用cron作業(yè)進行后臺處理。例如,假設有一個cron作業(yè),它編譯分析報告并通過電子郵件發(fā)送給用戶,并且系統(tǒng)每分鐘可以處理100個報告。一旦應用增長并且平均每分鐘開始獲得超過100個請求,處理效率將越來越滯后,那么將永遠無法完成所有工作。
在隊列系統(tǒng)中,可以通過設置多個工作人員來避免這種情況,每個工作人員可以選擇一個工作(每個工作包含100個報告)并且并行工作以更快地完成任務。
故障恢復
作為Web開發(fā)人員,我們會認為服務器和使用的API將始終連接,而現(xiàn)實情況則不同。網(wǎng)絡中斷非常普遍,我們所依賴的優(yōu)秀API可能因基礎(chǔ)設施問題而崩潰。因此,回到上面的報告舉例,如果生成報告的部分內(nèi)容要求你連接到API,并且該連接已關(guān)閉了2分鐘,那么200個報告失敗的情況會怎樣?
需要指出的是,隊列系統(tǒng)的學習確實十分耗費精力,它學習曲線陡峭,應用和部署的復雜性增加,隊列的作業(yè)無法始終以100%的精度控制。所以,該如何選擇趁手的隊列系統(tǒng)?以下將推薦五個適合后端開發(fā)人員的隊列系統(tǒng)。
Redis
Redis是鍵值存儲系統(tǒng),以前它只存儲,更新和檢索數(shù)據(jù)字符串,而不了解數(shù)據(jù)結(jié)構(gòu)。但今天Redis擁有高效且非常有用的數(shù)據(jù)結(jié)構(gòu),如列表,有序集,甚至是Pub-Sub系統(tǒng),這使得它非常適合于隊列實現(xiàn)。

Redis的優(yōu)勢:
完全的內(nèi)存數(shù)據(jù)庫,從而實現(xiàn)更快的讀/寫。
高效:每秒可輕松支持超過100000次讀/寫操作。
高度靈活的持久性方案??梢栽诔霈F(xiàn)故障時以可能的數(shù)據(jù)丟失為代價獲得最大性能,或者以完全保守的模式設置以犧牲性能以保持一致性。
集群支持開箱即用
需要注意的是,Redis沒有任何消息傳遞/排隊/恢復抽象,因此你需要使用軟件包或自己構(gòu)建輕量級系統(tǒng)。一個例子是Redis是Laravel PHP框架的默認隊列后端,其中調(diào)度程序已由框架作者實現(xiàn)。
RabbitMQ
Redis和RabbitMQ之間有一些細微的區(qū)別,所以讓我們先把它們弄清楚。
首先,RabbitMQ具有更專業(yè),定義明確的角色,因此它的構(gòu)建反映了消息傳遞。換句話說,它充當了兩個系統(tǒng)之間的中介,而Redis則不是這種情況,它充當數(shù)據(jù)庫。因此,RabbitMQ提供了Redis中缺少的一些工具:消息路由,重試,負載分配等。

任務隊列也可以被認為是一個消息傳遞系統(tǒng),其中調(diào)度程序,工作者和作業(yè)“提交者”可以被認為是參與消息傳遞的實體。
RabbitMQ的優(yōu)勢:
消息傳遞的更好抽象,如果你需要消息傳遞,則減少應用級別的工作。
對電源故障和停電更具彈性(至少在默認情況下比Redis更強)。
集群和聯(lián)合支持分布式部署。
用于管理和監(jiān)控部署的有用工具。
幾乎支持所有的編程語言。
可使用Docker,Chef,Puppet等進行部署。
什么時候使用RabbitMQ?當你需要使用異步消息傳遞,但是還沒有準備好解決這個列表中某些其他隊列選項的高度復雜性時,RabbitMQ是一個很好的選擇(見下文)。
ActiveMQ
如果你要構(gòu)建高度分布式的大型應用時,并且你不希望一直重新發(fā)明輪子,那么ActiveMQ值得一試。

ActiveMQ的優(yōu)勢:
它是用Java實現(xiàn)的,因此具有非常簡潔的Java集成(遵循JMS標準)。
支持多種協(xié)議:AMQP,MQTT,STOMP,OpenWire等。
開箱即用處理安全性,路由,消息過期,分析等。
為流行的分布式消息傳遞模式提供Baked-in支持,節(jié)省你的時間和代價高昂的錯誤。
ActiveMQ并不是僅適用于Java。它擁有Python,C/C ++,Node,.Net和其他生態(tài)系統(tǒng)的客戶端。此外,ActiveMQ建立在完全開放的標準之上,構(gòu)建自己的輕量級客戶端應該很容易。不過,ActiveMQ不包括后端。你仍然需要使用其中一個受支持的后端來存儲消息。
Amazon MQ
如果你認為ActiveMQ是能滿足需求的理想解決方案,但又不想自行構(gòu)建和維護基礎(chǔ)架構(gòu),那么Amazon MQ提供了托管服務來實現(xiàn)這一目標。它支持ActiveMQ所做的所有協(xié)議,功能完全沒有區(qū)別。
優(yōu)點是它是一個托管服務,因此除了使用它之外,你不必擔心任何其他問題。對于AWS上的那些部署更有意義,因為你可以直接從部署中利用其他服務和產(chǎn)品(例如,更快的數(shù)據(jù)傳輸)。
Beanstalkd
Beanstalkd是一個經(jīng)過實戰(zhàn)考驗,快速,簡單的后端隊列系統(tǒng)。Beanstalkd的一些特性使其與Redis有很大不同:
它嚴格來說是一個工作排隊系統(tǒng)而已。如果你的應用對消息傳遞的需求很小,那么請避免使用Beanstalkd。
沒有高級數(shù)據(jù)結(jié)構(gòu),如集合,優(yōu)先級隊列等。
Beanstalkd被稱為先進先出(FIFO)隊列。沒有辦法按優(yōu)先順序安排工作。
沒有集群選項。
所有這些都使得Beanstalkd能為服務器上的簡單項目提供一個靈活快速的隊列系統(tǒng)。對于許多人來說,它比Redis更快,更穩(wěn)定。因此,如果你遇到Redis問題,無論如何都無法解決,而且你的需求很簡單,那么Beanstalkd值得一試。