曾幾何時,我們還在尋找網路程式設計中c10k問題的解決方案。現在,從硬體和作業系統支援來看,「單台伺服器支援上萬併發連線」已經沒有多少挑戰性了。
現在的集群、分布式技術,可以將併發負載分擔到多台伺服器上。所以,只需要擴充套件出數十台伺服器,就可以解決問題。但是,我們更希望:更大程度地挖掘單台伺服器的資源,先努力垂直擴充套件,再進行水平擴充套件。這樣可以有效節省伺服器相關的開支(硬體資源、機房、運維人力、電力,其實也是一筆不小的開支)。
那麼,到底一台伺服器能夠支援多少tcp併發連線呢?這就是本文要討論的問題。
在linux下編寫網路伺服器程式,每乙個tcp連線都要佔乙個檔案描述符。一旦這個檔案描述符使用完了,新的連線到來時,系統返回給我們的錯誤是「socket/file:can't open so many files」。
這時你需要明白作業系統對可以開啟的最大檔案數的限制。
執行命令ulimit -n, 輸出 1024,說明:對於乙個程序而言,最多只能開啟1024個檔案。所以,如果你使用此預設配置,那麼最多也就可以併發上千個tcp連線。
1.1.1 臨時修改「程序開啟檔案控制代碼數限制」
使用命令:ulimit -n 1000000,但是這種臨時修改只對當前登入使用者目前的使用環境有效,系統重啟或使用者退出後就會失效。
1.1.2 重啟後失效修改「程序開啟檔案控制代碼數限制」(不過我在centos 6.5下測試,重啟後未發現失效)
1.1.3 永久修改「程序開啟檔案控制代碼數限制」
執行命令
cat /proc/sys/fs/file-nr
輸出 9344 0 592026
,含義分別為:
在kernel 2.6版本中,第二項的值總為0。這並不是乙個錯誤,它實際意味著:已經分配的檔案描述符無一浪費,都已經被使用 。
可以把這些數值改大些,用root許可權修改/etc/sysctl.conf 檔案:
作業系統上的埠號,1024以下是系統保留的,從1024-65535是使用者使用的。很多人都認為,由於每個tcp連線都要佔乙個埠號,所以我們最多可以有60000多個併發連線。但是,這種思路是錯誤的,
我們來分析一下吧。
系統用乙個四元組來唯一標識乙個tcp連線:。我們拿出《unix網路程式設計:卷一》第四章中對accept的講解,來看看概念性的東西,第二個引數cliaddr代表了客戶端的ip位址和埠號。而我們作為服務端,實際只使用了bind時這乙個埠,這說明埠號65535並不是併發量的限制。
server通常固定在某個本地埠上監聽,等待client的連線請求。不考慮位址重用(unix的so_reuseaddr選項)的情況下,即使server端有多個ip,本地監聽埠也是獨佔的。因此,在server端tcp連線四元組中,只有remote ip(也就是client ip)和remote port(客戶端port)是可變的。由此可知,最大tcp連線數為客戶端ip數×客戶端port數。對於ipv4,不考慮ip位址分類等因素,最大tcp連線數約為2的32次方(ip數)×2的16次方(port數),也就是說,server端單機最大tcp連線數約為2的48次方。
上面給出的結論都是理論上的單機tcp併發連線數,實際上單機併發連線數肯定要受硬體資源(記憶體)、網路資源(頻寬)的限制。一般情況下,對於數十萬併發連線的需求,還是採用集群、分布式技術,將併發負載分擔到多台伺服器上。但是,更大程度地挖掘單台伺服器的資源,先努力垂直擴充套件,再進行水平擴充套件,可以有效節省伺服器相關的開支。
單台伺服器最大支援多少連線數
在效能測試過程中,經常會接觸到鏈結數相關的問題,有乙個問題曾經困擾我好長時間,那就是一台伺服器最多能支援多少鏈結數呢?有的朋友可能會說是65535,因為作業系統有65535個埠,那麼這個答案準確嗎?這四個要素唯一確定乙個tcp鏈結,任意乙個要素不相同,就認為是乙個不同的鏈結。can t open s...
單台伺服器最大支援多少連線數
在效能測試過程中,經常會接觸到鏈結數相關的問題,有乙個問題曾經困擾我好長時間,那就是一台伺服器最多能支援多少鏈結數呢?有的朋友可能會說是65535,因為作業系統有65535個埠,那麼這個答案準確嗎?這四個要素唯一確定乙個tcp鏈結,任意乙個要素不相同,就認為是乙個不同的鏈結。can t open s...
優化 單台伺服器支援百萬級別tcp長連線
如何在單台伺服器上實現百萬級長連線,以下是實現該目標進行的一些優化 1.首先需要準備一台大記憶體的伺服器,裝上linux系統,比如rehat centos 核心版本在2.6.25之上 等。為什麼需要大記憶體,因為每個連線都需要有讀寫快取,具體看第二部內容 為什麼核心版本要在2.6.25之上,因為2....