1. 程式人生 > >初探佇列訊息:普通http同步請求、基於執行緒池的非同步請求、基於訊息佇列的請求三者的比較

初探佇列訊息:普通http同步請求、基於執行緒池的非同步請求、基於訊息佇列的請求三者的比較

最近忙完了手頭的專案,終於有時間研究之前一直落下的訊息隊列了,順帶手又看了一下多執行緒非同步請求,加上最傳統的http同步請求,正好可以拉出來做個比較,廢話不多說,走起!

場景設計:三個使用者同時向系統傳送一個請求,要求系統進行處理;

通過這個場景設計,我們來看看不同請求方式的表現:

1、普通http同步請求:系統同時接收到了這三個請求,由於是同步方式,因此需要按順序分別處理使用者1、使用者2、使用者3的請求;

這是一個學過java,寫過介面的童鞋都會使用的操作,三個請求被分配到了一個執行緒中,就像三輛汽車行駛在單車道上,如果車道里車輛不多,那沒問題,道路暢通,“城市”(系統伺服器

)通行狀態良好,但如果到了車輛通行的“高峰期”(高併發),那麼所有“車輛”都將堵在城市裡(請求會擁塞到伺服器端),造成城市交通的“擁擠”,甚至是交通“癱瘓”(伺服器擁塞、死鎖、直接宕機),影響整個城市的發展!

2、基於執行緒池的非同步請求:系統同時接收到了這三個請求,此時系統內部建立了一個執行緒池,會為這三個請求分配三個閒置的執行緒,通過非同步的方式去處理這三個請求,這樣1、2、3的請求無需排隊,都能被及時處理,不過由於三個執行緒要同時執行,對伺服器的效能就是一個考驗,在伺服器效能足夠支撐的情況下,這種方式無疑是最佳的;

為了避免出現1的那種情況,作為“城市規劃師”的你,決定升級城市的交通

(升級伺服器),拓寬車道(設定執行緒池),將車道升級到三車道,這樣城市的通行能力(系統性能)就增長到了原來的三倍!原本三輛車要擠到一條道路上,現在三輛車被分配到了三條道上(三個請求分配給了三個執行緒),從而解決了擁堵的問題。然而,隨著城市的不斷髮展壯大,更多的“車輛”(請求)湧入城市,而且道路由於負載過重,也出現了損壞(伺服器硬體損耗),天氣不好的情況(網路狀況不好)也常常出現,城市交通又再次每況愈下...

3、基於訊息佇列的請求:使用者的三個請求先分配到一個佇列訊息中(通常這個佇列會放到另一臺伺服器中,與系統伺服器區分開),系統一直在監聽著這個佇列的請求訊息,一旦系統處理完當前請求,就會從佇列中取出下一條訊息,以此類推。在這種模式下,及時系統所在伺服器宕機,也不會影響佇列中的請求,待伺服器恢復後,佇列中等待的訊息仍可以被系統繼續處理,這種方式可以代償性的解決高併發的問題,代價就是請求的等待時間,如果是一些短時間高併發但又不需要及時響應(如秒殺)

的請求,可以採用這種方式。

由於城市預算的問題(伺服器效能受限),道路無法再進行拓寬,但還是有源源不斷的車輛湧入,再繼續這樣下去,城市又將陷入癱瘓!無奈之下,你只好想了一招權宜之計:在城市入口處設立關卡,車輛在城外排隊(佇列訊息),在保證城市安全流量的基礎上,在交警的監控下(監聽佇列訊息),放行車輛入城。這樣雖說一定程度上影響了車輛入城的速度(請求速度),但是保證了城市的穩定(伺服器穩定)和車輛本身的安全(請求不會丟失)!

綜合看下來,多執行緒當然是速度最優的方式,不過它比較依賴伺服器的配置,由於都是在系統內部進行,也存在這請求丟失的風險;佇列訊息是價效比最優的方式,不吃配置,請求不會因系統的問題而丟失,而且佇列訊息所在的伺服器一般都比較穩定(畢竟沒有什麼業務操作),不過它無法提升訪問速度;其實呢,每種方式都有利有弊,最重要的還是要看你面對的業務邏輯和實際情況。

這篇是純理論,以後有時間,我也會從程式碼的角度來談談具體的實現。

最後,希望本文對你的“城市規劃”,有所幫助!