一種基于消息隊列的消費均衡方法及系統的制作方法
【技術領域】
[0001]本發明涉及基于消息隊列的計算機通信技術領域,特別是涉及一種基于消息隊列的消費均衡方法及系統。
【背景技術】
[0002]消息隊列系統(又名消息中間件)被廣泛的用于各個互聯網公司。作為消息的一種緩沖機制,它可以有效的減輕公司后臺服務器的壓力。
[0003]—個典型的消息隊列系統的結構示意圖如圖1所示,一共由三部分組成:
[0004]1.生產者端:負責向消息隊列發送消息的終端。
[0005]2.消費者端:從消息隊列中獲得消息的終端。
[0006]3.消息隊列:用于存儲消息的中間件。通常來說,消息隊列系統的中間件包括多個消息隊列,這些消息隊列用于存儲生產者端發送過來的消息。消息隊列通常設置在至少一臺服務器上,在實際操作中通常為多臺服務器。
[0007]由于這種系統是由三部分組成,所以可以有多個生產者端向同一個中間件發送消息,也有可能會有多個消費者端從中間件中拉取消息,進行消費。
[0008]舉例來說,對于電商而言,用戶作為生產者端,其產生的訂單會被首先發送至消息隊列,然后其他程序作為消費者端,會從該消息隊列中拉取消息進行消費,即對訂單進行處理。采用消息隊列的好處是:不管前臺產生訂單的速度如何迅猛,通過中間消息隊列的緩存,可以保證后臺程序的正常運行,從而避免了網絡波峰可能對后臺服務器造成的壓力。
[0009]不僅如此,消息隊列還被廣泛用在及時通訊等應用中。比如當兩臺終端通訊時,首先由終端一發送了一條消息給自己的好友,該消息會被緩存在消息隊列中,繼而被推送至對應好友的終端的軟件中。這種設計的好處是,當好友不在線(即沒有打開對應的軟件時),消息隊列可以被當作一種數據的存儲工具。由于不需要提供查詢、刪除等操作,所以使用消息隊列作為存儲工具,比傳統的數據庫要高效很多。
[0010]以下為消息隊列系統的具體工作方式:
[0011]生產者端一般采用輪詢的方式向各個消息隊列輪流發送消息,例如中間件中一共有3個消息隊列,那么生產者端會采用“消息隊列1-消息隊列2-消息隊列3-消息隊列1-消息隊列2-消息隊列3”這種順序,分別向各個消息隊列發送消息。
[0012]對于消費者端,目前,對于絕大數消息隊列系統,消費者端都可以自己決定每次從中間件拉取多少條消息,而所拉取的消息是從一個消息隊列獲取還是從多個消息隊列獲取一般由系統本身決定。目前而言,大多數開源系統采用輪詢的方式,輪流的從各個消息隊列獲取消費者端需要的消息。例如,當有三個消息隊列的時候,消費者端如果先后發送了獲取1條消息,10條消息,100條消息的命令,那么系統會相應的從消息隊列1獲取1條消息給消費者端,從消息隊列2獲取10條消息給消費者端,從消息隊列3獲取100條消息給消費者端。
[0013]但是,目前的消費方案存在消費不均衡的現象。所謂消費均衡,即為各個消息隊列的未消費消息數大致相等。目前的絕大數消息隊列系統在以下幾個場景中會出現消費不均衡的現象:
[0014]場景一,當生產者端沒有嚴格按照輪詢的方式向各個消息隊列發送消息,但是消費者端依然采用輪詢的方式來消費,此時就會造成某個消息隊列中的消息積壓。例如,假設有3個消息隊列,而生產者端輪詢的向3個消息隊列發送消息,但是并不是每次都發送1條,而是給消息隊列1發送10條消息,給消息隊列2發送100條消息,給消息隊列3發送1000條消息。那么如果消費者端仍然按照輪詢均勻的消費,那么消息隊列3的消息會嚴重積壓。
[0015]場景二,生產者端并非均勻消費。例如,消費者端可以按照每次1條消息,10條消息,100條消息的順序從各個消息隊列拉取消息,那么消息隊列3的消息會被消費得很快,而消息隊列1的消息會消費的很慢,盡管這兩個消息隊列的消息生產時間也許是一致的,同樣造成了消費不均衡的狀態。
[0016]場景三,服務器集群的某個節點宕機。消息隊列往往支持分布式部署,多個消費隊列可能分布在不同的節點上,當一個節點宕機之后,該節點上存儲的消費隊列不能繼續接收消息,但是其他在線的節點仍然在接收消息,或者消費端仍在從其他在線節點消費消息。當該節點從故障中恢復過來之后,其存儲的消息數量要小于其他節點上消費隊列的消息數量。所以,此時,也必須采取某種均衡方式,對消費進行負載均衡。
[0017]基于以上情況,如何讓消費者端做到消費自動均衡是本領域亟待解決的問題,目前各個開源系統都沒有完美的解決這一問題。業界目前的做法,即采取上面的做法(輪詢的方法)來發送和消費消息。由于生產者端和消費者端大多數情況下也是由同一支開發團隊所設計開發,所以只能在嚴格設定生產者端和消費者端按照均勻輪詢方法運作的前提下,來維持消費均衡。
[0018]基于此,業界目前并沒有提出一種通用的消費均衡解決方案,使得它可以在各個情況下均適用。即,即使生產者端和消費者端未按照均勻輪詢方法運作,也能維持消費均衡,提高適用性。
【發明內容】
[0019]本發明解決的技術問題是,提出一種通用的自動完成消費均衡的方法和系統。
[0020]更進一步,本發明不用考慮消費者端需要的消息數量,生產者端是以何種策略向隊列發送消息,也不用考慮宕機所帶來的潛在風險,在各種情況下,均可保證消費均衡。
[0021 ] 為了解決上述問題,本發明公開了一種基于消息隊列的消費均衡方法,包括:
[0022]排序步驟,消費者端實時依照多個消息隊列的未消費消息數,對該多個消息隊列進tx排序;
[0023]消費步驟,當消費者端所執行的任一線程需要消費消息時,均以未消費消息數最大的消息隊列作為目標隊列,從該目標隊列中獲取消息,進行消費。
[0024]該消費步驟之后還包括維護步驟:消費完畢后,獲取該目標隊列的當前未消費消息數并反饋至該排序步驟。
[0025]該排序步驟進一步包括:利用一異步更新線程,輪詢該多個消息隊列,實時獲得多個消息隊列的未消費消息數,并據以對該多個消息隊列進行實時排序。
[0026]所述方法利用堆結構實現該排序步驟。
[0027]所述方法在執行該消費步驟的過程中,該堆結構將對應該目標隊列的堆頂節點刪除,并標記為不可用,調整剩余節點的順序,在該消費步驟執行完畢后,將該目標隊列的節點重新加入該堆結構。
[0028]本發明還公開了一種基于消息隊列的消費均衡系統,包括:
[0029]排序單元,用于使得消費者端實時依照多個消息隊列的未消費消息數,對該多個消息隊列進行排序;
[0030]消費單元,用于當消費者端所執行的任一線程需要消費消息時,均以未消費消息數最大的消息隊列作為目標隊列,從該目標隊列中獲取消息,進行消費。
[0031]該系統還包括維護單元:用于在消費完畢后,獲取該目標隊列的當前未消費消息數并反饋至該排序單元。
[0032]該排序單元進一步包括一異步更新線程,用于輪詢該多個消息隊列,實時獲得多個消息隊列的未消費消息數,并據以對該多個消息隊列進行實時排序。
[0033]該排序單元利用堆結構來實現。
[0034]所述系統在調用該消費單元的過程中,該堆結構將對應該目標隊列的堆頂節點刪除,并標記為不可用,調整剩余節點的順序,在對該消費單元的調用結束后,將該目標隊列的節點重新加入該堆結構