單機伺服器支援千萬級併發長連線的壓力測試

2022-06-08 10:57:09 字數 3657 閱讀 7989

很早以前就聽說了c10k,c100k,c1000k等問題,每個問題的解決都是併發程式設計的乙個里程碑。隨著硬體的快速提公升,那麼10m(千萬)併發連線呢?能否做到?如何做到?會有什麼限制?小編對此很好奇,折騰了不少時間,終於有了令人興奮的答案!

下面我們使用

庫自帶的例子程式,來跑出乙個單機千萬併發連線的例項,先上操作步驟,後面解釋。

10m連線,大家的個人電腦肯定無法滿足要求,如果不是在大公司任職,弄個實際的物理機對大家是個奢望。那麼怎麼辦?我也面臨同樣問題。

現在的雲計算這麼發達,還可以按小時計費,一小時的費用也就幾元,那就試試雲計算產品吧。小編先是在阿里雲上測試,但阿里雲的按需付費主機配置不高,費了不少時間,最終只跑到了3m個連線。阿里雲的不行,是主機的配置問題還是程式的問題呢?為了得到最終的結論,我嘗試了其他的雲產品,最終ucloud的雲主機給了我驚喜。

首先建立ucloud主機

ucloud主機(一共需要兩台,一台作為伺服器,一台作為客戶端):

. 選擇主機管理的建立主機

. 系統選擇ubuntu14.4 64bit (小編的測試程式是c++11,需要高版本的g++)

. 機型標準版

. 網路增強一定要選擇開啟 (千萬連線是網路io密集型,網路當然要強大型)

. cpu 16核 記憶體64g 資料盤0

. 下一步中的網路型別選擇基礎網路即可,建立主機之後,需要購買彈性ip,並且繫結到主機

. **:小編實驗時(2023年8月),上述的配置,一台僅需7.2元一小時,兩台不到15元

做實驗的時候,大家記得要眼疾手快哦,一小時十幾元,獲得了自己想要的結果就趕緊釋放主機哈

10m併發連線對系統是個挑戰,需要調整相關的引數

sysctl -w fs.file-max=10485760 #系統允許的檔案描述符數量10m

sysctl -w net.ipv4.tcp_rmem=1024 #每個tcp連線的讀取緩衝區1k,乙個連線1k

sysctl -w net.ipv4.tcp_wmem=1024 #每個tcp連線的寫入緩衝區1k

#修改預設的本地埠範圍

sysctl -w net.ipv4.ip_local_port_range='1024 65535'

sysctl -w net.ipv4.tcp_tw_recycle=1 #快速**time_wait的連線

sysctl -w net.ipv4.tcp_tw_reuse=1

sysctl -w net.ipv4.tcp_timestamps=1

#使用者單程序的最大檔案數,使用者登入時生效

echo '* soft nofile 1048576' >> /etc/security/limits.conf

echo '* hard nofile 1048576' >> /etc/security/limits.conf

ulimit -n 1048576 #使用者單程序的最大檔案數 當前會話生效

下面可以開始部署我們的測試程式了

apt-get update

apt-get install -y screen git make g++ nload iptraf

git clone

cd handy

git checkout 97b5426f91d37

make -j4

選取一台主機s作為伺服器,執行伺服器

10m/10m-svr 100 300 10 301 #啟動10個子程序,每個程序分別監聽100-300的埠

選取另一台主機c作為客戶端,執行客戶端,(需要填寫s的內網ip)

#啟動10個客戶端子程序,連線到s的100-300埠,發起10m個連線,在500秒內建立所有的連線,每600秒傳送乙個心跳,心跳資料為64位元組,多程序的管理埠為301

10m/10m-cli 100 300 10000000 500 10 600 64 301

觀察結果

然後,10m連線的建立就不需要更多的步驟啦,使用命令

watch ss -s

我們就可以開始觀察連線的建立進度啦,看著連線漸漸的往上走,超過10k,100k, 1m是不是很有成就感。

併發連線數到達千萬時,有諸多方面的問題需要解決:

. 單程序最大檔案數量限制:limit -n 最多能把這個數字修改到1048575,因此單個程序最多能夠開啟百萬個檔案,千萬併發連線需要千萬個檔案描述符,於是我們使用多程序來做到千萬檔案的支援

.多程序之間的負載均衡:nginx使用多程序來增加自己的吞吐量,原先採用共享鎖的方式來平衡負載,對核數較多的伺服器,較多的程序並沒有達到效能的線性提公升。最新的linux核心引入了so_reuseport選項,該選項可以自動平衡監聽同一埠的多程序,是核心級的解決方案。handy採用該方案,優於nginx的舊有方式(最新的nginx也支援so_reuseport)。

.測試中客戶端本地埠不夠:讓伺服器監聽了200個埠,這樣客戶端連線伺服器的每個埠只有50k個連線,然後加大預設的本地埠範圍就可以滿足要求(見前面的伺服器系統引數)

測試中如果一次性建立千萬個連線,則絕大部分的連線建立都會失敗,因此讓客戶端每100ms建立2000個連線,提高連線建立的成功率。

系統在執行中,並沒有多少的負載,當然啦,一部分負載跑到底層的hypervisor去了

小編實驗的機器上記憶體占用大約40g,平均乙個連線前後一共用了4k,不多不多

大家可以通過iptraf,nload等工具來檢視系統的網路情況

寫到這裡,順便給出我測是的ucloud主機的效能引數吧:

網絡卡流量最多可以到1.2gbit/s,並非所有時間都到了這麼高,並不穩定,一般在800m-1.2g之間波動

tcp收包發包的最高qps是12w/s,多了就上不去了

為了達到千萬條連線,折騰了不少問題,上面只是個大概,有些地方的細節並沒有深入**。如果大家有興趣,後續會慢慢把其他細節分享出來。

--------2017-12-02更新測試結果-------

最近看見阿里推出了網路增強型伺服器,pps能夠達到450w,於是拿handy的千萬連線進行了測試。在阿里雲上面,按量購買無法購買到最高配的虛機,最高的只購買了下面機型:

網路增強型,60w pps,16核,64g

命令如下

handy/10m/10m-svr 100 500 16 501 #伺服器

handy/10m/10m-cli 100 500 10000000 150 16 170 64 501 # 150s建立1千萬連線

能夠完成千萬條連線,達到的pps大約是20w,進一步增加網路負載會導致一定程度丟包,這個qps與主機聲稱的60w差距較大,可能跟當時共享的機器有關

網路增強型,100wpps,8核,32g

命令如下

handy/10m/10m-svr 100 500 16 501 #伺服器

handy/10m/10m-cli 100 500 6500000 30 16 40 64 501 # 30s 建立650w連線

32g記憶體只到650w連線,達到的pps大約是65w,進一步增加網路負載會導致一定程度丟包

handy的各個測試中,應用的效能都會隨著主機的效能提公升而提公升,瓶頸主要是在系統的記憶體和網絡卡io處

Web伺服器 併發伺服器 長連線(3 4 4)

每次new socket都被強制關閉,造成短連線 所提不要關閉套接字 但是不關閉的話,瀏覽器不知道發完沒有啊 此時用到header的屬性content length 將http body的長度裝到返回頭,送出給瀏覽器 當瀏覽器獲取完資料了之後,就不會再載入了 設定非堵塞 tcp sever sock...

Web伺服器 併發伺服器 長連線(3 4 4)

目錄 每次new socket都被強制關閉,造成短連線 所提不要關閉套接字 但是不關閉的話,瀏覽器不知道發完沒有啊 此時用到header的屬性content length 將http body的長度裝到返回頭,送出給瀏覽器 當瀏覽器獲取完資料了之後,就不會再載入了 設定非堵塞 tcp sever s...

linux伺服器調整引數支援高併發

服務端調整系統的引數,在 etc sysctl.conf中 net.core.somaxconn 2048 net.core.rmem default 262144 net.core.wmem default 262144 net.core.rmem max 16777216 net.core.wm...