大家好,我是小林。
最近有讀者面試騰訊的時(shí)候,被問到 2 個(gè)很有意思的問題:
一個(gè)服務(wù)端進(jìn)程最大能支持多少條 TCP 連接?
一臺服務(wù)器最大能支持多少條 TCP 連接?
很多同學(xué)第一反應(yīng)就是端口的限制,端口號最多是 65536個(gè),那就最多只能支持 65536 條 TCP 連接。
實(shí)際上這是不對的!
今天都帶大家分析一波這兩個(gè)問題。
一個(gè)服務(wù)端進(jìn)程最多能支持多少條 TCP 連接?
首先我們要知道 TCP 連接本質(zhì)上在內(nèi)核里就是一個(gè) socket 對象。
structsocket{ .... //INET域?qū)S玫囊粋€(gè)socket表示,提供了INET域?qū)S械囊恍傩?,比如IP地址,端口等 structsock*sk; //TCP連接的狀態(tài):SYN_SENT、SYN_RECV、ESTABLISHED..... shorttype; .... }; structinet_sock{ ... __u32daddr;//IPv4的目標(biāo)地址。 __u16dport;//目標(biāo)端口。 __u32saddr;//源地址。 __u16sport;//源端口。 ... };
這個(gè) socket 對象也就是一個(gè)數(shù)據(jù)結(jié)構(gòu),里面包含了 TCP 四元組的信息:源IP、源端口、目標(biāo)IP、目標(biāo)端口。
TCP 四元組
所以, 只要確認(rèn)了【源IP、源端口、目標(biāo)IP、目標(biāo)端口】這四個(gè)信息,就能在內(nèi)核中找到這個(gè) socket 對象,也就能確定一條 TCP 連接。
一個(gè)服務(wù)端進(jìn)程通常是監(jiān)聽 1 個(gè)端口號(當(dāng)然也可能監(jiān)聽多個(gè)端口號,這里不考慮),比如我的圖解網(wǎng)站的 nginx 服務(wù),就監(jiān)聽了 443 端口。
你們看圖解網(wǎng)站的時(shí)候,實(shí)際上就是通過 nginx 服務(wù)把網(wǎng)頁數(shù)據(jù)發(fā)送給你們的。
然后,服務(wù)端進(jìn)程除了會固定監(jiān)聽某個(gè)一個(gè)端口之外,也通常會綁定 0.0.0.0 IP 地址。
這個(gè)IP地址是特殊的, 0.0.0.0 指的是本機(jī)上的所有IPV4地址,如果一個(gè)主機(jī)有兩個(gè) IP 地址,192.168.1.1 和 10.1.2.1,并且該主機(jī)上的一個(gè)服務(wù)監(jiān)聽的地址是0.0.0.0,那么通過兩個(gè) IP 地址都能夠訪問該服務(wù)。
所以一個(gè)服務(wù)端進(jìn)程,意味著他的 IP地址和端口號是固定的(0.0.0.0:443)。
也就是當(dāng)客戶端與服務(wù)端建立一條 TCP 連接的時(shí)候,這個(gè) TCP 連接的四元組信息中服務(wù)端的 IP地址和端口號是固定的,能產(chǎn)生變化的就是客戶端的 IP 地址和端口號了。
因此,一個(gè)服務(wù)端進(jìn)程最大能支持的 TCP 連接個(gè)數(shù)的計(jì)算公式如下:
對 IPv4,客戶端的 IP 數(shù)最多為 2 的 32 次方,客戶端的端口數(shù)最多為 2 的 16 次方。
那么一個(gè)服務(wù)端進(jìn)程理想情況下,最大的 TCP 連接數(shù)約為 2 的 48 次方(2^32 (ip數(shù)) * 2^16 (端口數(shù)),這數(shù)值是非??鋸埖牧耍s等于兩百多萬億!
當(dāng)然,服務(wù)端進(jìn)程最大能支持的 TCP 連接數(shù)遠(yuǎn)不能達(dá)到理論上限,還會受到文件描述符、內(nèi)存大小資源的限制,畢竟 socket 在 Linux 的視角其實(shí)就是文件資源,而且一個(gè) socket 對象也會占用一定的內(nèi)存資源。
因此,會受以下因素影響:
文件描述符限制,每個(gè) TCP 連接都是一個(gè)文件,如果文件描述符被占滿了,會發(fā)生 Too many open files。Linux 對可打開的文件描述符的數(shù)量分別作了三個(gè)方面的限制:
系統(tǒng)級:當(dāng)前系統(tǒng)可打開的最大數(shù)量,通過 cat /proc/sys/fs/file-max 查看;
用戶級:指定用戶可打開的最大數(shù)量,通過 cat /etc/security/limits.conf 查看;
進(jìn)程級:單個(gè)進(jìn)程可打開的最大數(shù)量,通過 cat /proc/sys/fs/nr_open 查看;
內(nèi)存限制,每個(gè) TCP 連接都要占用一定內(nèi)存,操作系統(tǒng)的內(nèi)存是有限的,如果內(nèi)存資源被占滿后,會發(fā)生 OOM。
一臺服務(wù)器最大最多能支持多少條 TCP 連接?
前面分析是一個(gè)服務(wù)端進(jìn)程理的情況,理論上能最大支持約為 2 的 48 次方(2^32 (ip數(shù)) * 2^16 (端口數(shù)),約等于兩百多萬億!
那到了一臺服務(wù)器的視角就會有一點(diǎn)不一樣。
一臺服務(wù)器是可以有多個(gè)服務(wù)端進(jìn)程的,每個(gè)服務(wù)端進(jìn)程監(jiān)聽不同的端口,比如:ssh的22,Redis的6339,當(dāng)然所有65535個(gè)端口你都可以用來監(jiān)聽一遍。
當(dāng)然所有65535個(gè)端口你都可以用來監(jiān)聽一遍,這樣理論上線就到了2的32次方(ip數(shù))×2的16次方(port數(shù))×2的16次方(服務(wù)器port數(shù))個(gè),感興趣你可以算一下,這個(gè)基本相當(dāng)于無窮個(gè)了。
不過理想和實(shí)際總是會有差距的!
因?yàn)長inux每維護(hù)一條TCP連接都要花費(fèi)資源,處理連接請求,保活,數(shù)據(jù)的收發(fā)時(shí)需要消耗一些CPU,維持TCP連接主要消耗內(nèi)存。
我們題目的問題是考慮最大多少個(gè)連接,所以我們先不考慮數(shù)據(jù)的收發(fā),那么TCP在靜止的狀態(tài)下,就不怎么消耗CPU了,主要消耗內(nèi)存,而Linux上內(nèi)存是有限的。
首先,我們要知道一條處于 ESTABLISH 狀態(tài)的 TCP 連接具體占用多大內(nèi)存?
一個(gè) TCP 對象占用的大小,等于它所包含的一些數(shù)據(jù)結(jié)構(gòu)占用大小的總和,也是就把上面這些數(shù)據(jù)結(jié)構(gòu)的大小累加起來,就是一個(gè) TCP 連接占用的大小了。
這里直接給大家一個(gè)結(jié)論,一條處于 ESTABLISH 狀態(tài)的 TCP 連接占用的大小是 3.44 KB(0.81K+2.19K+0.19K+0.25K)。
TCP對象內(nèi)存開銷總結(jié)
也就是,每一條靜止?fàn)顟B(tài)的TCP連接大約需要吃 3.44K 的內(nèi)存。
那么 8 GB 物理內(nèi)存的服務(wù)器,最大能支持的 TCP 連接數(shù)=8GB/3.44KB=2,438,956(約240萬)!
當(dāng)然, 實(shí)際過程中的 TCP 連接,肯定不是靜止?fàn)顟B(tài)的,還會進(jìn)行發(fā)送數(shù)據(jù)和接收數(shù)據(jù)了,那么這些過程還是會額外消耗更多的內(nèi)存資源的,并發(fā)很難達(dá)到百萬級別。
總結(jié)
一個(gè)服務(wù)端進(jìn)程最多能支持多少條 TCP 連接?
如果在不考慮服務(wù)器的內(nèi)存和文件句柄資源的情況下,理論上一個(gè)服務(wù)端進(jìn)程最多能支持約為 2 的 48 次方(2^32 (ip數(shù)) * 2^16 (端口數(shù)),約等于兩百多萬億!
但是在實(shí)際中是支持不了這個(gè)數(shù)值的,每個(gè) TCP 連接都是一個(gè)文件,會占用文件句柄資源,也會占用一定的內(nèi)存空間。
一臺服務(wù)器最大最多能支持多少條 TCP 連接?
一臺服務(wù)器是可以有多個(gè)服務(wù)端進(jìn)程的,每個(gè)服務(wù)端進(jìn)程監(jiān)聽不同的端口,當(dāng)然所有65535個(gè)端口你都可以用來監(jiān)聽一遍。
當(dāng)然所有65535個(gè)端口你都可以用來監(jiān)聽一遍,這樣理論上線就到了2的32次方(ip數(shù))×2的16次方(port數(shù))×2的16次方(服務(wù)器port數(shù))個(gè),這個(gè)基本相當(dāng)于無窮個(gè)了。
但是 Linux每維護(hù)一條TCP連接都要花費(fèi)內(nèi)存資源的,每一條靜止?fàn)顟B(tài)(不發(fā)送數(shù)據(jù)和不接收數(shù)據(jù))的 TCP 連接大約需要吃 3.44K 的內(nèi)存,那么 8 GB 物理內(nèi)存的服務(wù)器,最大能支持的 TCP 連接數(shù)=8GB/3.44KB=2,438,956(約240萬)。
實(shí)際過程中的 TCP 連接,還會進(jìn)行發(fā)送數(shù)據(jù)和接收數(shù)據(jù)了,那么這些過程還是會額外消耗更多的內(nèi)存資源的,并發(fā)很難達(dá)到百萬級別。
審核編輯:劉清
-
Linux
+關(guān)注
關(guān)注
87文章
11496瀏覽量
213220 -
TCP
+關(guān)注
關(guān)注
8文章
1400瀏覽量
80638
原文標(biāo)題:騰訊三面:一臺服務(wù)器,最大支持的TCP連接數(shù)是多少?
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
如何標(biāo)識一個(gè)TCP連接
AT+CIPSERVERMAXCONN查詢/設(shè)置服務(wù)器允許建立的最大連接數(shù)是幾個(gè)呢?
服務(wù)器超出了連接范圍的解決方法
Linux的TCP Server最大連接數(shù)是多少?
怎樣把設(shè)計(jì)的library移動(dòng)到另一臺服務(wù)器上去?
如何將整個(gè)POST參數(shù)字符串傳遞到另一臺服務(wù)器?
有沒有人有多個(gè)LWIP客戶端通過一個(gè)端口連接到一臺服務(wù)器的示例?
租用一臺服務(wù)器多少錢?
一臺Linux服務(wù)器最多能支撐多少個(gè)TCP連接?
單臺服務(wù)器支持的TCP并發(fā)連接數(shù)
用舊手機(jī)DIY一臺服務(wù)器
一臺服務(wù)器最大能建立多少條TCP連接呢?
服務(wù)器數(shù)據(jù)恢復(fù)—服務(wù)器陣列磁盤進(jìn)水損壞的數(shù)據(jù)恢復(fù)案例

評論