linux如何處理多連線請求?

小二郎**發表於2019-05-23

1.TCP迭代伺服器程式

這種方式就是伺服器同一時間只處理一個客戶端的請求,這個請求處理完以後才轉向下一個客戶請求。當然這樣的伺服器程式比較少見,這就像一個公司只能一次處理一個客戶,後面的客戶只能等待,這樣的話肯定是不行的,效率太低 了,但是要是從程式控制角度來看這種方式是最快的,因為它沒有執行程式控制,這是相對於後面講的方式多程式而言的,啥意思呢,就是說一個公司裡面當你只有一個銷售員接待客戶的時候,我對銷售員的管理成本就沒有了,當你是多個銷售員對應多個客戶的時候,雖然這個時候可以同時接待多個客戶,但是老闆對多個銷售員的管理成本也要算進去,上面說的程式控制就是老闆對多個銷售員的管理。

2.TCP併發伺服器程式,每個客戶一個子程式

這種方式呢,就是多個程式處理多個連線,每來一個新的連線,就立即建立(fork)一個新的子程式來處理這個連線,這種方式的問題是為每個新連線現場fork一個子程式比較耗費cpu時間,作業系統在fork子程式時要做的事情很多的,首先需要複製父程式的相關資料結構,然後在初始化許可權,排程器,檔案系統,記憶體這一系列操作,所以建立一個子程式的開銷是很大的,尤其是現在這個時代,繁忙的伺服器每天的連線數可以達到數以百萬計。

舉例來說這種方式就像你作為老闆,每接一個專案就建立一個新的子公司,這個子公司的人員,桌椅板凳,各種工具都是新的,專案完成以後該子公司解散。

3.TCP預先派生子程式伺服器程式

這種方式就是在啟動階段預先建立多個子程式,當各個客戶連線到來時,子程式就可以馬上為他們服務,而不是說當客戶來的時候在建立好子程式為他們服務,這種方式優點就是沒有了父程式fork的開銷,缺點就是父程式必須在伺服器啟動階段猜測需要預先建立多少子程式,而且父程式還要實時監控程式池中的程式數,當這個數字高於某個閾值時,需要終止多餘的程式,當這個數字低於某個閾值時,需要建立新程式。

舉例來說:這就像老闆預先建立了多個子公司,當來專案時,讓建立好的子公司接專案就可以 了,而不是像第二種方式那樣,來客戶了,你再去建立子公司,但是作為老闆你要全域性把控,當你發現子公司的數量太多,已經遠大於專案的數量,這時候你就要登出掉一部分公司,以節省開銷,同樣反過來,當你發現接的專案數很多,增長的速度很多,那麼你就需要馬上在建立幾個子公司來處理專案,要不然你的專案就接不到了,就掙不了錢,無法迎娶白富美,走上人生巔峰了。

然後我們再說關於這種方式會發生的一個問題,這個問題就叫做"驚群",啥意思呢,就是說當來了一個新請求時,所有的程式都會被喚醒,但是最後只有一個程式能接到這個請求,這樣就會導致效能受損。

舉例來說:當沒有專案來的時候,所有的子公司都處於放假狀態,所有人員都休息了,然後來了一個新的專案,所有的公司都得恢復到上班狀態,但是其實到最後只有一個公司能接到這個專案,這樣對於其他子公司員工來說是不是有點煩,老子正在放假休息呢,然後你把我召回到了公司還沒事情做,讓我白跑一趟,交通費食宿費這些都屬於浪費掉了,對應到作業系統來說就是效能受損。

4.TCP併發伺服器程式,每個客戶一個執行緒

這種方式就是每來一個客戶請求,就建立一個執行緒,建立執行緒的開銷要比建立程式的開銷小多了,建立執行緒就是將各個結構的引用計數加一,建立棧等操作,相對比建立程式來說開銷要小很多了,這其實就像公司接專案的時候不是建立子公司,而是建立多個專案組,專案組可以共用公司的各種資源。

這裡說一下accept的概念,accept是套接字(socket)中的一個函式,他是用來接收伺服器中已完成連線佇列裡面的連線,也就是伺服器會有一個佇列專門用來存放已經三次握手完成的tcp連線,當這個佇列有資料的時候,呼叫這個accept函式就會從佇列頭部拿出一個連線給應用程式處理。

5.TCP預先建立執行緒伺服器程式,每個執行緒各自accept

這種其實就是伺服器啟動階段預先建立執行緒池,也就是多個執行緒以取代為每個客戶連線現場建立一個執行緒有效能加速效果,這種做法就像來了一個新專案,只有一個專案組接這個專案,其他專案組還是做原來做的事情。

6.TCP預先建立執行緒伺服器程式,主執行緒統一accept

這種方式就是在程式啟動階段建立一個執行緒池之後只讓主執行緒呼叫accept並把每個客戶連線傳遞給池中某個可用執行緒,這就像有個所有專案組的總管,他負責接專案,來了專案以後,他去把這個專案分配給可以開發的專案組。

相關文章