拆解一下任務佇列、訊息佇列、任務排程系統

2022-09-22 12:00:55

最近調研了下任務排程系統中介軟體,包括xxl-job、elastic-job等,發現跟任務佇列有一些類似的能力,比如通過API(事件)觸發任務執行。

隨即想到,能否用任務排程系統覆蓋任務佇列的場景呢?

另外,一直以來,很多同學也經常會產生困惑,任務佇列和訊息佇列究竟有什麼區別?

因此,本文通過多個維度來進行拆解,試著分析 任務佇列、訊息佇列、任務排程系統 這三類中介軟體 究竟有哪些不同,究竟誰更適合什麼場景。

  • 從基本功能說起
  • 對比系統角色
  • 本質區別
  • 總結

1、從基本功能說起

什麼是訊息佇列?

訊息佇列大家基本是耳熟能詳,不管是經典的kafka、rocketmq,還是新興的pulsar。
雖然它們在架構上都有所區別,但是本質上都是一種 應用 對 應用的 「通訊方式」。
應用程式通過讀寫出入佇列的「訊息」來通訊,而無需對等直接連線應用。主要解決應用耦合、非同步訊息、流量削鋒等問題,用來實現高效能,高可用,可伸縮和最終一致性架構。

什麼是任務排程系統?

任務排程系統也是大家比較熟悉的,從quartz到xxl-job,到elastic-job。
主要解決的問題是,解決分散式場景下的 離線任務、定時任務 的排程問題,具備高可用、視覺化、可運維、低延時等能力。
一些複雜場景,可能還需要進行任務編排(DAG)執行。

什麼是任務佇列?

任務佇列可能聽過的人會少一點,沒有特別出名的java開源框架,相對活躍一點的包括Celery、Resque等。
它解決的問題是比較經典的,線上業務如何 實時 處理 長耗時 任務。
任務佇列通過封裝 非同步任務傳送、任務處理、任務狀態儲存、例外處理 等環節,提供了一套完整的處理長耗時任務的程式設計框架,實現了 隔離性、容錯性 的應用架構。

2、對比系統角色

2.1 任務佇列 VS 訊息佇列

認識一個系統,除了通過文字簡單瞭解基本功能外,最直接的方式是看看整體系統架構的角色。

先看下訊息佇列的系統角色。

 

主要包括:

  • 生產者 Producer
    釋出訊息的角色。Producer通過 MQ 的負載均衡模組選擇相應的 Broker 叢集佇列進行訊息投遞,投遞的過程支援快速失敗和重試。
  • 消費者 Consumer
    訊息消費的角色。
  • 代理伺服器 Broker
    Broker主要負責訊息的儲存、投遞和查詢以及服務高可用保證。

然後,我們看看任務佇列的系統角色包括哪些。

 

主要包括4類角色:

  • 任務生產者 Producer
    釋出任務的角色。Producer通過 MQ 的負載均衡模組選擇相應的 Broker 叢集佇列進行訊息投遞,投遞的過程支援快速失敗和重試。
  • 消費者 Consumer
    消費任務的角色。
  • 佇列queue
    Broker主要負責任務的儲存、投遞和查詢以及服務高可用保證。
  • 任務狀態持久化storage
    storage主要負責任務的狀態持久化、查詢等能力。可以選擇獨立的DB,也可以直接複用queue。

通過系統角色對比,我們可以看到,訊息佇列是任務佇列的其中一個角色,任務佇列中queue的選型可以是訊息佇列kafka、rocketmq,甚至可以是能提供類似能力的redis。

除了queue之外,任務佇列的一個顯著特點是,一般還需要一個storage系統角色來持久化任務的狀態。

2.2 任務佇列 VS 任務排程系統

任務排程系統比較有代表性的開源產品包括Quartz、Elastic-job、XXL-JOB。

我們以XXL-JOB為例,來看下系統角色。

 

包括2個角色:

  • 排程模組(排程中心):
    負責管理排程資訊,按照排程設定發出排程請求,自身不承擔業務程式碼。排程系統與任務解耦,提高了系統可用性和穩定性,同時排程系統效能不再受限於任務模組;
  • 執行模組(執行器):
    負責接收排程請求並執行任務邏輯。任務模組專注於任務的執行等操作,開發和維護更加簡單和高效。接收「排程中心」的執行請求、終止請求和紀錄檔請求等。

從這裡能看出,XXL-JOB是一個典型的「中心化」系統,任務都是根據預設規則從 排程中心 發起,然後由執行器來執行。當然,Elastic-job中的ElasticJob-lite也有「去中心化」方案,但是從邏輯模型的角度來說,仍然是一個需要排程中心進行排程的。

而任務佇列的整個模型就是一個「去中心化」、「應用 對 應用 生產消費」系統,任務由producer發起,由consumer消費。

3、本質區別

結合前面的基本功能和系統角色,我們可以更好地體會三個中介軟體的本質區別。

訊息佇列本質上都是一種 應用 對 應用 的 「通訊方式」,主要解決應用耦合、非同步訊息、流量削鋒等問題。

任務佇列本質上是一種封裝好的 應用 對 應用 非同步任務 「程式設計框架」,它封裝了對非同步任務的如何重試、如何消費、如何獲取任務結果、如何監控任務的執行情況 等等問題,讓業務開發只關心業務邏輯。
同時,任務佇列也是一種典型的 「架構風格」,這個程式設計框架 指導 業務開發對 長耗時 任務從普通 線上業務 的服務中拆分出來,避免影響線上業務的穩定性。因此,任務佇列的主要應用場景也是 線上業務。

任務排程系統設計之初就是為了解決分散式場景下的 離線任務、定時任務 的排程問題,它的設計目標是 輕量級、視覺化、易擴充套件。
因此,它的設計沒有 應用 對 應用 的生產消費概念,也不具備對高流量的承受能力(削峰)。
當然,它跟任務佇列最大的區別,它不具備將 長耗時 任務從普通 線上業務 的服務中拆分出來的這種架構思想指導(大部分定時任務都是在夜間執行)。

任務排程系統的定位還是應用於 輕量級、離線業務 場景最為合適。

4、總結

回過頭看看一開始的兩個問題。

1)能否用任務排程系統覆蓋任務佇列的場景呢?

不能。任務排程系統適用於 輕量級、離線業務 場景下的 定時任務 和 離線任務,使用排程/執行模式,不具備承接線上業務高流量的能力。而任務佇列適用於 線上業務 場景下的 長耗時任務,使用 生產消費模式,具備對高流量的承受能力(削峰)。

2)任務佇列和訊息佇列究竟有什麼區別?

任務佇列是一個封裝好的 非同步任務程式設計框架,也是一種 長耗時任務 與 普通線上業務 拆分的架構思想。訊息佇列只是任務佇列中的一個系統角色。

總結一下,其實三者的差異還是非常大的。

 

 

希望能夠拋磚引玉,提供一些啟發和思考。如果你有其他補充和建議,歡迎留言討論。

 

都看到最後了,原創不易,點個關注,點個贊吧~
文章持續更新,可以微信搜尋「阿丸筆記 」第一時間閱讀,回覆【筆記】獲取Canal、MySQL、HBase、JAVA實戰筆記,回覆【資料】獲取一線大廠面試資料。
知識碎片重新梳理,構建Java知識圖譜:github.com/saigu/JavaK…(歷史文章查閱非常方便)