1. 程式人生 > >伺服器端接受多個請求時的高併發處理

伺服器端接受多個請求時的高併發處理

同步服務為每個請求建立單一執行緒,由此執行緒完成整個請求的處理:接收訊息,處理訊息,返回資料;這種情況下伺服器資源對所有入棧請求開放,伺服器資源被所有入棧請求競爭使用,如果入棧請求過多就會導致伺服器資源耗盡宕機,或者導致競爭加劇,資源排程頻繁,伺服器資源利用效率降低。

非同步服務則可以分別設定兩個執行緒佇列,一個專門負責接收訊息,另一個專門負責處理訊息並返回資料,另有一些值守執行緒負責任務派發和超時監控等工作。在這種情況下無論入棧請求有多少,伺服器始終依照自己的能力處理請求,伺服器資源消耗始終在一個可控的範圍。這種模式的一個問題就是這兩個執行緒佇列的大小如何根據機器負載情況動態調整。

對於非同步服務模式:

這種情況下,雖然入棧請求以訊息佇列的方式被非同步處理但每個請求內部卻是採用阻塞的方式訪問外部資源,如果外部資源訪問速度過慢,可能導致請求處理佇列中的所有執行緒均處於阻塞狀態,此時CPU使用率雖然很低但是卻因為佇列中執行緒已滿而無法處理訊息佇列中的新訊息,此時若能調整執行緒佇列最大執行緒數將可提高CPU利用率。但另一個問題是如果執行緒數被調高之後所有執行緒的IO處理突然結束並且接下來每個執行緒都將進行大量計算的話那麼CPU可能出現過載。

在系統執行的每個時間點上,當時正在進行IO的執行緒數量和正在進行計算的執行緒數量是不斷變化著的,那麼如何才能設計出一個可以根據系統當時情況自動適應負載變化的高度自適應的系統呢?

在這方面採用反應式計算模型確實能設計出適應負載能力很強的系統,系統利用率和吞吐量可以大幅提高,但這種系統仍然可能會出現系統區域性負載過高的風險。

採用反應式計算模型,不僅系統中的入棧請求以訊息佇列的方式得以非同步化,而且系統中所有的IO任務也必需依照此法行之,這些IO任務的處理需要採用非同步模型(如NIO)。另外要考慮的就是如何劃分非同步IO訊息併為其配置執行緒隊列了,比如是要將所有IO任務放入統一的佇列還是為某類IO任務設定單獨的佇列。

伺服器資源雖然由系統分配但大多以執行緒為持有者被執行緒持有並使用,如執行緒堆疊,被執行緒持有的各類鎖等資源。