後端開發人員的 6 大排隊系統
已發表: 2019-08-09您在尋找排隊系統嗎? 或者,也許您正在尋找更好的? 這裡有你需要的所有信息!
排隊系統是後端開發中保存最完好的秘密。
不想寫一首讚美隊列系統的詩,我會說一個初級後端開發人員在學會將隊列集成到系統中之後就變成了一個中級後端開發人員。 隊列改善了客戶體驗(我們將看到如何)、降低複雜性並提高系統的可靠性。
當然,對於流量接近於零的非常簡單的 Web 應用程序和宣傳冊網站,隊列可以是一個整體(如果您在典型的共享主機環境中,甚至無法安裝),但重要的應用程序都將從隊列中受益系統和大型應用程序在不涉及排隊的情況下是不可能的。
在我們開始之前,一個免責聲明:如果您已經對排隊系統感到滿意並且想要比較各種選項,那麼接下來的幾個介紹部分將導致大量睡眠。 所以請隨意跳到前面。 介紹部分適用於那些對排隊系統只有模糊概念或只是順便聽到這個名字的人。
什麼是排隊系統?
讓我們從了解什麼是隊列開始。
隊列是計算機科學中的一種數據結構,它模仿我們在我們周圍看到的真實世界的隊列。 例如,如果你去售票櫃檯,你會注意到你必須站在隊列的末端,而隊列開始的人會先拿到票。 這也就是我們所說的“先到先得”現象。 在計算機科學中,可以編寫將它們的任務像這樣存儲在隊列中的程序,並在相同的先到先得的基礎上逐個處理它們。
請注意,隊列本身並不進行任何實際處理。 它只是各種臨時存儲,任務等待它們被某些東西拾取。 如果這一切聽起來有點過於抽象,請不要擔心。 這是一個抽象的概念,但我們將在下一節中看到清晰的示例。
為什麼需要排隊系統?
在不進行非常冗長的描述的情況下,我會說排隊系統的主要需求是因為後台處理、並行執行和故障恢復。 讓我們藉助示例來看看這些:
後台處理
假設您正在運行一個電子商務營銷活動,其中時間至關重要,並且您的應用程序被構建為在客戶完成付款之前觸發確認電子郵件並顯示“謝謝”頁面。 如果您連接的郵件服務器出現故障,網頁就會死掉,破壞用戶體驗。
想像一下您會收到大量的支持請求! 在這種情況下,最好將此電子郵件發送任務推送到作業隊列並向客戶顯示成功頁面。
並行執行
許多開發人員,尤其是那些主要編寫更簡單、低流量應用程序的開發人員,都習慣於使用 cron 作業進行後台處理。 這很好,直到輸入的大小變得如此之大以至於無法清除。 例如,假設您有一個 cron 作業來編譯分析報告並將其通過電子郵件發送給用戶,並且您的系統每分鐘可以處理 100 個報告。
一旦您的應用程序增長並開始平均每分鐘收到超過 100 個請求,它將開始越來越落後,並且永遠無法完成所有工作。
在排隊系統中,可以通過設置多個工作人員來避免這種情況,每個工作人員可以選擇一項工作(每個工作包含 100 個要完成的報告)並並行工作以更快地完成任務。
從失敗中恢復
作為 Web 開發人員,我們通常不會認為失敗。 我們理所當然地認為我們的服務器和我們使用的 API 將始終在線。 但實際情況有所不同——網絡中斷太常見了,而且您所依賴的優秀 API 可能由於基礎設施問題而停機(在您說“不是我!”之前,不要忘記大規模的 Amazon S3 中斷)。 那麼,回到報告示例,如果您的報告生成的一部分需要您連接到支付 API,並且該連接中斷了 2 分鐘,那麼 200 個失敗的報告會發生什麼情況?
不過,排隊系統確實涉及相當大的開銷。 當您進入一個全新的領域時,學習曲線非常陡峭,您的應用程序和部署的複雜性會增加,並且排隊的作業無法始終以 100% 的精度進行控制。 也就是說,在某些情況下構建沒有隊列的應用程序是不可能的。
順便說一下,讓我們看一下當今排隊後端/系統中的一些常見選項。
雷迪斯
Redis 被稱為鍵值存儲,它只存儲、更新和檢索數據字符串,而不知道數據的結構。 雖然這在早期可能是正確的,但今天 Redis 擁有高效且非常有用的數據結構,如列表、排序集,甚至是 Pub-Sub 系統,使其非常適合隊列實現。
Redis 的優點是:
- 完全在內存中的數據庫,導致更快的讀/寫。
- 高效:可以輕鬆支持每秒100,000次以上的讀/寫操作。
- 高度靈活的持久性方案。 您可以在發生故障的情況下以可能丟失數據為代價獲得最大性能,也可以設置為完全保守模式以犧牲性能以保持一致性。
- 開箱即用支持的集群
請注意,Redis 沒有任何消息傳遞/隊列/恢復抽象,因此您要么需要使用包,要么自己構建輕量級系統。 一個例子是 Redis 是 Laravel PHP 框架的默認隊列後端,框架作者已經實現了一個調度器。
學習 Redis 很容易。
兔MQ
Redis 和 RabbitMQ 之間有一些細微的區別,所以讓我們先把它們排除在外。
首先,RabbitMQ 有一個更專業、定義明確的角色,因此它的構建就是為了反映這一點——消息傳遞。 換句話說,它的最佳點是充當兩個系統之間的中介,而 Redis 則不是這種情況,它充當數據庫。 因此,RabbitMQ 提供了一些 Redis 中缺少的功能:消息路由、重試、負載分配等。
如果你考慮一下,任務隊列也可以被認為是一個消息傳遞系統,其中調度程序、工作人員和作業“提交者”可以被認為是參與消息傳遞的實體。
RabbitMQ 具有以下優點:
- 更好的消息傳遞抽象,如果你需要消息傳遞,減少應用程序級的工作。
- 對電源故障和斷電更具彈性(至少默認情況下比 Redis)。
- 分佈式部署的集群和聯合支持。
- 用於管理和監控部署的有用工具。
- 支持幾乎所有重要的編程語言。
- 使用您選擇的工具(Docker、Chef、Puppet 等)進行部署。
何時使用 RabbitMQ? 當您知道需要使用異步消息傳遞但還沒有準備好解決此列表中其他一些排隊選項的巨大復雜性時,我會說這是一個很好的選擇(見下文)。

活動MQ
如果您進入企業領域(或構建高度分佈式和大規模的應用程序),並且您不想一直重複發明輪子(並在此過程中犯錯誤),那麼 ActiveMQ 值得一看.
這是 ActiveMQ 擅長的地方:
- 它是用 Java 實現的,因此具有非常簡潔的 Java 集成(遵循 JMS 標準)。
- 支持多種協議:AMQP、MQTT、STOMP、OpenWire 等。
- 開箱即用地處理安全、路由、消息過期、分析等。
- 對流行的分佈式消息傳遞模式的內置支持,為您節省時間和代價高昂的錯誤。
這並不是說 ActiveMQ 僅適用於 Java。 它擁有 Python、C/C++、Node、.Net 和其他生態系統的客戶端,因此不必擔心未來可能會崩潰。 此外,ActiveMQ 建立在完全開放的標準之上,構建自己的輕量級客戶端應該很容易。
說了這麼多,請注意 ActiveMQ 只是一個代理,不包括後端。 您仍然需要使用受支持的後端之一來存儲消息。 我將它包含在這裡是因為它不依賴於特定的編程語言(如其他流行的解決方案,如 Celery、Sidekiq 等)
亞馬遜 MQ
Amazon MQ 值得在這裡快速但重要地提及。 如果您認為 ActiveMQ 是滿足您需求的理想解決方案,但又不想自己處理構建和維護基礎設施,Amazon MQ 提供了一項託管服務來實現這一點。 它支持 ActiveMQ 所做的所有協議——在功能上完全沒有區別——因為它在表面下使用了 ActiveMQ 本身。

優點是它是一項託管服務,因此您無需擔心使用它以外的任何事情。 這對於 AWS 上的部署更有意義,因為您可以直接從您的部署中利用其他服務和產品(例如,更快的數據傳輸)。
亞馬遜 SQS
我們不能指望亞馬遜在關鍵基礎設施方面坐以待斃,不是嗎?
因此,我們有了 Amazon SQS,它是由知名巨頭 AWS 提供的完全託管的簡單隊列服務(字面意思)。 再次強調,細微的差別很重要,所以請注意 SQS 沒有消息傳遞的概念。 與 Redis 一樣,它是一個簡單的後端,用於在隊列中接受和分發作業。
那麼,您想在什麼時候使用 Amazon SQS? 以下是一些原因:
- 你是 AWS 的粉絲,不會碰其他任何東西(老實說,有很多這樣的人,我認為這沒有什麼問題)。
- 您需要一個託管解決方案,以確保故障率為零並且不會丟失任何作業。
- 您不想構建一個集群並且必須自己監控它。 或者更糟的是,當您可以利用這段時間進行生產性開發時,必須構建監控工具。
- 您已經在 AWS 平台上進行了大量投資,並且保持鎖定狀態具有商業意義。
- 您需要一個集中的、簡單的排隊系統,沒有任何與消息傳遞、協議等相關的絨毛。
總而言之,對於想要將作業隊列合併到系統中而不必擔心自己安裝/監控事物的人來說,Amazon SQS 是一個不錯的選擇。
豆莖
Beanstalkd 已經存在了很長時間,並且是一個久經考驗、快速、簡單的作業隊列後端。 Beanstalkd 的一些特點使其與 Redis 有很大不同:
- 嚴格來說,這是一個工作排隊系統,僅此而已。 你把工作推到它上面,這些工作後來被工作人員拉走。 因此,如果您的應用程序對消息傳遞的需求很小,那麼您應該避免使用 Beanstalkd。
- 沒有像集合、優先級隊列等高級數據結構。
- Beanstalkd 是所謂的先進先出 (FIFO) 隊列。 沒有辦法按優先級安排工作。
- 沒有集群選項。
所有這一切都說 Beanstalkd 為在單個服務器上運行的簡單項目提供了一個靈活且快速的隊列系統。 對許多人來說,它比 Redis 更快、更穩定。 因此,如果您在使用 Redis 時遇到了似乎無論如何都無法解決的問題,並且您的需求很簡單,那麼 Beanstalkd 值得一試。
結論
如果您已經閱讀到這裡(或到達此處略讀),那麼您很有可能對排隊系統感興趣或需要一個。 如果是這樣,此頁面上的列表將為您提供很好的服務,除非您正在尋找特定於語言/框架的隊列系統。
我希望我能告訴你排隊很簡單而且 100% 可靠,但事實並非如此。 這很混亂,因為這一切都在後台並且發生得非常快(錯誤可能會被忽視並變得非常昂貴)。 儘管如此,隊列仍然非常必要,而且您會發現它們是您武器庫中的強大武器(甚至可能是最強大的武器)。 祝你好運!