linux基於1臺服務端服務器、一臺客戶端服務器建立百萬長連接?

可能做網絡相關開發的你知道一個server上一個ip 最多隻能使用65535個,為什麼是65535因為linux下,這裡如果還要減去系統保留的那就更少了,至於系統保留多少,可以通過以下配置進行配置:

/proc/sys/net/ipv4/ip_local_port_range

或者是通過sysctl進行永久配置。

linux下標識一個連接是通過四元組標識的即:「源ip,源端口;目標ip,目標端口」,所以對於一臺只有一個ip的客戶機和服務端能建立的連接是可以計算出來的。

所以如果你要對你寫的服務是否能夠支撐100萬長連接,如果按照60000(這裡只考慮一臺服務器只有一個ip可用(感謝條友提醒,特意備註下以免大家誤解)一臺客戶機服務器來算,那麼需要17臺服務器。(這裡假設每個客戶機上都是一個網卡)那麼我們有有沒有更好的辦法來測試100萬長連接,而不需要17個客戶端服務器。

用17個客戶端服務器來建立100萬長連接肯定是可行的,但是浪費資源,增加部署工作負擔。

下面簡單介紹下一些可行以及不可行的方案如何基於1臺服務端服務器、一臺客戶端服務器建立100萬長連接:

1. 服務端服務器添加多個虛擬網卡,綁定不同的ip,然後讓服務端程序監聽在不同的ip上監聽不同的端口。但是服務器端的端口最多也只能使用65535個。這個我沒有嘗試過,理論上是不可行的,大家可以試下然後告訴我~【不可行】

2.客戶端服務器添加多個虛擬網卡,比如20個,分別綁定不同的ip,最終也沒法逃過65535個端口的約束【不可行】

3. 使用SO_REUSEPORT 特性,這是google 提交的一個linux 補丁。該補丁做什麼工作呢?

它支持多個進程或者線程綁定到同一端口,提高服務器程序的性能。這裡的綁定是bind,可以是客戶端、也可以是服務端。linux內核(>= 3.9)支持SO_REUSEPORT特性。

所以我們可以利用該補丁來建立100萬連接。

1)首先服務端程序需要監聽17個端口,可以是一個ip

2)其次在客戶端側便利本地可用的端口範圍,每個port 需要跟服務端的17個端口進行建立連接。

每個端口第一次連接調用connect 時需要把對應的socket 設置SO_REUSEPORT開關打開,然後在該socket上指定本地端口(用bind來綁定即可)。然後用同樣的方法對服務端第一個端口調用connect,依次類推,只要客戶機上內存足夠,100萬長連接完全是沒有問題的。

int sfd = socket(domain, socktype, 0);
int optval = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
bind(sfd, (struct sockaddr *) &addr, addrlen);

當然這種測試方法對於要求測試高併發的請求量是,有一定的侷限性的。

管理SO_REUSEPORT特性還可以用來解決,服務端多worker 監聽模型中的驚群效應。

linux基於1臺服務端服務器、一臺客戶端服務器建立百萬長連接?

Fig 1 多worker監聽模型

關於SO_REUSEPORT 原理請參考:https://lwn.net/Articles/542629/


分享到:


相關文章: