首頁/ 汽車/ 正文

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

最大併發tcp連線數是多少呢?

首先,問題中描述的65535個連線指的是客戶端連線數的限制。

在tcp應用中,server事先在某個固定埠監聽,client主動發起連線,經過三次握手後建立tcp連線。那麼對單機,其最大併發tcp連線數是多少呢?

如何標識一個TCP連線

在確定最大連線數之前,先來看看系統如何標識一個tcp連線。系統用一個4四元組來唯一標識一個TCP連線:{localip, localport,remoteip,remoteport} = {本地ip,本地port,遠端ip,遠端port}

client最大tcp連線數

client每次發起tcp連線請求時,除非繫結埠,通常會讓系統選取一個空閒的本地埠(local port),該埠是獨佔的,不能和其他tcp連線共享。tcp埠的資料型別是unsigned short,因此本地埠個數最大隻有65536,埠0有特殊含義,不能使用,這樣可用埠最多隻有65535,所以在全部作為client端的情況下,一個client最大tcp連線數為65535,這些連線可以連到不同的serverip。

server最大tcp連線數

server通常固定在某個本地埠上監聽,等待client的連線請求。不考慮地址重用(unix的SO_REUSEADDR選項)的情況下,即使server端有多個ip,本地監聽埠也是獨佔的,因此server端tcp連線4元組中只有remoteip(也就是clientip)和remote port(客戶端port)是可變的,因此最大tcp連線為客戶端ip數×客戶端port數,對IPV4,不考慮ip地址分類等因素,最大tcp連線數約為2的32次方(ip數)×2的16次方(port數),也就是server端單機最大tcp連線數約為2的48次方。

實際的tcp連線數

上面給出的是理論上的單機最大連線數,在實際環境中,受到機器資源、作業系統等的限制,特別是sever端,其最大併發tcp連線數遠不能達到理論上限。在unix/linux下限制連線數的主要因素是記憶體和允許的檔案描述符個數(每個tcp連線都要佔用一定記憶體,每個socket就是一個檔案描述符),另外1024以下的埠通常為保留埠。

所以,對server端,透過增加記憶體、修改最大檔案描述符個數等引數,單機最大併發TCP連線數超過10萬,甚至上百萬是沒問題的。

這明顯是進入了思維的誤區,65535是指可用的埠總數,並不代表伺服器同時只能接受65535個併發連線。

舉個例子:

我們做了一個網站,繫結的是TCP的80埠,結果是所有訪問這個網站的使用者都是透過伺服器的80埠訪問,而不是其他埠。可見埠是可以複用的。

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

即使Linux伺服器只在80埠偵聽服務, 也允許有10萬、100萬個使用者連線伺服器。Linux系統不會限制連線數至於伺服器能不能承受住這麼多的連線,取決於伺服器的硬體配置、軟體架構及最佳化。

01

我們知道兩個程序如果需要進行通訊最基本的一個前提是:能夠唯一的標示一個程序。在本地程序通訊中我們可以使用PID來唯一標示一個程序,但PID只在本地唯一,網路中的兩個程序PID衝突機率很大。

這時候就需要另闢它徑了,IP地址可以唯一標示主機,而TCP層協議和埠號可以唯一標示主機的一個程序,這樣可以利用IP地址+協議+埠號唯一標示網路中的一個程序。

能夠唯一標示網路中的程序後,它們就可以利用socket進行通訊了。socket(套接字)是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層複雜的操作抽象為幾個簡單的介面供應用層呼叫以實現程序在網路中通訊。

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

socket源自Unix,是一種“開啟—讀/寫—關閉”模式的實現,伺服器和客戶端各自維護一個“檔案”,在建立連線開啟後,可以向自己檔案寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉檔案。

02

唯一能夠確定一個連線有4個東西:

伺服器的IP

伺服器的Port

客戶端的IP

客戶端的Port

伺服器的IP和Port可以保持不變,只要客戶端的IP和Port彼此不同就可以確定一個連線數。

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

一個socket是可以建立多個連線的,一個TCP連線的標記為一個四元組(source_ip, source_port, destination_ip, destination_port),即(源IP,源埠,目的IP,目的埠)四個元素的組合。只要四個元素的組合中有一個元素不一樣,那就可以區別不同的連線。

舉個例子:

你的主機IP地址是1。1。1。1, 在8080埠監聽

當一個來自 2。2。2。2 發來一條連線請求,埠為5555。這條連線的四元組為(1。1。1。1, 8080, 2。2。2。2, 5555)

這時2。2。2。2又發來第二條連線請求,埠為6666。新連線的四元組為(1。1。1。1, 8080, 2。2。2。2, 6666)

那麼,你主機的8080埠建立了兩條連線;

(2。2。2。2)發來的第三條連線請求,埠為5555(或6666)。第三條連線的請求就無法建立,因為沒有辦法區分於上面兩條連線。

同理,可以在同一個埠號和IP地址上繫結一個TCP socket和一個UDP socket

因為埠號雖然一樣,但由於協議不一樣,所以埠號是完全獨立的。

TCP/UDP一般採用五元組來定位一個連線:

source_ip, source_port, destination_ip, destination_port, protocol_type

即(源IP,源埠,目的IP,目的埠,協議號)

綜上所述,伺服器的併發數並不是由TCP的65535個埠決定的。伺服器同時能夠承受的併發數是由頻寬、硬體、程式設計等多方面因素決定的。

所以也就能理解淘寶、騰訊、頭條、百度、新浪、嗶嗶嗶嗶等為什麼能夠承受住每秒種幾億次的併發訪問,是因為他們採用的是伺服器叢集。伺服器叢集分佈在全國各地的大型機房,當訪問量小的時候會關閉一些伺服器,當訪問量大的時候會不斷地開啟新的伺服器。

轉載自 https://blog。csdn。net/daocaokafei/article/details/115410761

65535從哪來的,幹啥的?

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

要解釋好這個問題,就要先說清楚65535的含義。在Linux系統中,如果兩個機器要通訊,那麼相互之間需要建立TCP連線,為了讓雙方互相認識,Linux系統用一個四元組來唯一標識一個TCP連線:{local ip, local port, remote ip, remote port},即本機IP、本機埠、遠端IP、遠端埠,IP和埠就相當於小區地址和門牌號,只有拿到這些資訊,通訊的雙方才能互相認知。在Linux系統中,表示埠號(port)的變數佔16位,這就決定了埠號最多有2的16次方個,即65536個,另外埠0有特殊含義不給使用,這樣每個伺服器最多就有65535個埠可用。因此,65535代表Linux系統支援的TCP埠號數量,在TCP建立連線時會使用。

TCP怎麼建立連線,與埠號是什麼關係?

Linux伺服器在互動時,一般有兩種身份:客戶端或者伺服器端。典型的互動場景是:

(1)伺服器端主動建立監聽的socket,並繫結對外服務埠port,然後開始監聽

(2)客戶端想跟伺服器端通訊時,就開始連線伺服器的埠port

(3)服務端接受客戶端的請求,然後再生成新的socket

(4)伺服器和客戶端在新的socket裡進行通訊

可以看到,埠port主要用在伺服器和客戶端的“握手認識”過程,一旦互相認識了,就會生成新的socket進行通訊,這時候port就不再需要了,可以給別的socket通訊去使用,所以很明顯TCP連線的數量可以大於TCP埠號的數量65,535。

考慮一下兩個極端場景,即某臺Linux伺服器只作為客戶端或者伺服器端

(1)Linux伺服器只作為客戶端

這時候每發起一個TCP請求,系統就會指定一個空閒的本地埠給你用,而且是獨佔式的,不會被別的TCP連線搶走,這樣最多可以建立65535個連線,每個連線都與不同的伺服器進行互動。這種場景,就是題主所描述的樣子,但是由於條件過於苛刻,屬於小機率事件,所以更多的還是理論上的可能,現實的環境中幾乎不會出現。

(2)Linux伺服器只作為服務端

這種場景下,服務端就會固定的監聽本地埠port,等著客戶端來向它發起請求。為了計算簡單,我們假設伺服器端的IP跟埠是多對一的,這樣TCP四元組裡面就有remote ip和remote port是可變的,因此最大支援建立TCP個數為2的32次方(IP地址是32位的)乘以2的16次方(port是16位的)等於2的48次方。

現實中單臺Linux伺服器支援的TCP連線數量

透過前面的分析我們知道,在現實場景中,由於存在埠port複用的情況,伺服器可同時支援的TCP連線數跟65535沒有一一對應關係,事實上,真正影響TCP連線數量的,是伺服器的記憶體以及允許單一程序同時開啟檔案的數量,因為每建立一個TCP連線都要建立一個socket控制代碼,每個socket控制代碼都佔用一部分系統記憶體,當系統記憶體被佔用殆盡,允許的TCP併發連線數也就到了上限。一般來講,透過增加伺服器記憶體、修改最大檔案描述符個數等,可以做到單臺伺服器支援10萬+的TCP併發。

linux的TCP連線數量最大不能超過65535?那伺服器如何應對併發?

當然,在真實的商用場景下,單臺伺服器都會編入分散式叢集,透過負載均衡演算法動態的排程不同使用者的請求給最空閒的伺服器,如果伺服器平均記憶體使用超過80%的警戒線,那麼就會及時採用限流或者擴充套件叢集的方式來保證服務,絕對不會出現伺服器的記憶體被耗盡的情況,那樣就算事故了。

總之,65535只是Linux系統中可使用埠port數量的上限,埠port數量與TCP連線數量並非完全一一對應的關係,伺服器支援的TCP併發連線數量主要跟伺服器的記憶體以及允許單個程序同時開啟的檔案數量有關係,透過埠複用及調整伺服器引數等手段,單臺伺服器支援的TCP併發連線數是可以高於65535的。

原文連結:https://mp。weixin。qq。com/s/k_6Oi-_z-MpdytSvFSLN0A

相關文章

頂部