實(shí)戰(zhàn)單機(jī)50萬Tcp連接

實(shí)戰(zhàn)單機(jī)50萬Tcp連接

本來準(zhǔn)備嘗試挑戰(zhàn)百萬鏈接, 但是申請(qǐng)不到機(jī)器資源, 只好在自己的筆記本上來跑測(cè)試. 機(jī)器配置如下:

Memory: 11.4 GiB
Intel? Core? i5-5200U CPU @ 2.20GHz × 4

技術(shù)框架選擇的是Vert.x, 這是比Netty更好的服務(wù)端框架. 連續(xù)測(cè)試幾天, 最終壓到了48萬, 過程中也遇到了很多問題(小馬過河, 水深水淺得走下去試試才知道啊), 文末的鏈接給了很多幫助.

準(zhǔn)備工作

Server端服務(wù)器配置

1.修改系統(tǒng)最大文件打開數(shù)。

臨時(shí)性方案:echo 1200000 > /proc/sys/fs/file-max

永久性方案:在/etc/sysctl.conf中添加fs.file-max = 1200000,設(shè)置完成后執(zhí)行命令:sudo sysctl -p,重新裝載配置使其生效歉眷。

查看當(dāng)前系統(tǒng)使用的打開文件描述符數(shù):cat /proc/sys/fs/file-nr

 ~/WorkSpace/Java/vert.x   sc  cat /proc/sys/fs/file-nr 
11069   0   2000000

執(zhí)行命令會(huì)輸出三個(gè)數(shù)值戴陡,第一個(gè)表示當(dāng)前系統(tǒng)已分配使用的文件數(shù)褂萧,第二個(gè)數(shù)為分配后已釋放的(目前已不再使用),第三個(gè)數(shù)是系統(tǒng)最大文件數(shù)嫂冻,等于file-max值胶征。

2.修改進(jìn)程最大文件打開數(shù)。

這個(gè)參數(shù)默認(rèn)值比較小桨仿,我的ubuntu14.04上默認(rèn)是1024個(gè)睛低。如果我們創(chuàng)建大量的鏈接,當(dāng)超過這個(gè)值時(shí)將會(huì)拋出:Too many open files錯(cuò)誤服傍。

首先钱雷,查看本機(jī)的默認(rèn)最大文件打開數(shù):ulimit -n。如果我們想創(chuàng)建一百萬鏈接的話吹零,這個(gè)值應(yīng)該設(shè)置大于1000000的值罩抗。

臨時(shí)修改方案,這種方案及時(shí)生效灿椅,但是重啟系統(tǒng)后配置丟失套蒂。

ulimit -Sn 1200000
ulimit -Hn 1200000

永久修改方案,需要修改/etc/security/limits.conf茫蛹,*代表非root用戶操刀。如果只想為某一個(gè)用戶設(shè)置的話*換成用戶名即可。

*         hard    nofile      1200000
*         soft    nofile      1200000
root      hard    nofile      1200000
root      soft    nofile      1200000

保存修改需重啟系統(tǒng)或者重新登錄使配置生效婴洼。

我們可以啟動(dòng)一個(gè)進(jìn)程來看一下它的最大文件打開數(shù):cat /proc/${pic}/limits骨坑。以下數(shù)據(jù)是我啟動(dòng)的一個(gè)vertx Server進(jìn)程:

 ~/WorkSpace/Java/vert.x   sc  cat /proc/27136/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             46651                46651                processes 
Max open files            1200000              1200000              files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       46651                46651                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us     

可以看到open files一行已經(jīng)變成我們的預(yù)設(shè)值。在修改的時(shí)候需要注意一點(diǎn)ulimit的之不能超過系統(tǒng)的max file size柬采。

我的ubuntu 17.04在做這個(gè)修改的時(shí)候遇到一點(diǎn)問題卡啰,設(shè)置完成后重啟系統(tǒng)静稻,啟動(dòng)程序發(fā)現(xiàn)最大打開文件總是4096。折騰了半天發(fā)現(xiàn)是ubuntu系統(tǒng)的bug匈辱。解決方案來自這里振湾。

3.TCP協(xié)議棧優(yōu)化

Client端服務(wù)器配置

1.修改端口范圍。

linux服務(wù)器上端口范圍是0~65535亡脸,其中0~1024是給系統(tǒng)保留的端口范圍押搪。當(dāng)客戶端建立鏈接的時(shí)候會(huì)自動(dòng)的選擇一個(gè)本地可用的端口號(hào),為了能夠最大限度的利用機(jī)器上的端口浅碾,我們需要修改端口范圍大州。

通過命令cat /proc/sys/net/ipv4/ip_local_port_range我們可以查看當(dāng)前的端口范圍配置。

修改的話我們?cè)?etc/sysctl.conf中添加這行:net.ipv4.ip_local_port_range= 1024 65535垂谢,然后重載配置厦画。這樣的話一個(gè)client服務(wù)器可以創(chuàng)建六萬多個(gè)鏈接(我本機(jī)測(cè)試64500個(gè)鏈接)。

即便是這樣我們也需要大概17臺(tái)客戶端測(cè)試機(jī)滥朱,這我上哪搞去啊根暑。只能通過虛擬IP來弄了(系統(tǒng)知識(shí)嚴(yán)重匱乏,網(wǎng)上找了很長時(shí)間才搞定)徙邻。接下來我們來配置虛擬IP排嫌。配置虛擬IP我們可以通過ifconfig來搞。比如我們直接執(zhí)行命令:sudo ifconfig eth0:0 192.168.199.100 netmask 255.255.255.0缰犁。eth0是真實(shí)網(wǎng)卡的名字淳地,eth0:0是虛擬網(wǎng)卡的名字,后邊是網(wǎng)卡綁定的IP帅容。如果要想局域網(wǎng)訪問颇象,這個(gè)IP要和你真實(shí)網(wǎng)卡上的IP在同一網(wǎng)段。本地訪問的話就隨意了并徘。

還有另外一種方式是修改/etc/network/interfaces配置文件夯到。我們添加一下條目:

auto eth0:0
iface eth0 inet static
address 192.168.1.201
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.0

添加完成后,重啟network service:sudo /etc/init.d/networking restart饮亏。通過執(zhí)行ifconfig便可看到這個(gè)虛擬IP耍贾。

為啥一個(gè)server不能創(chuàng)建超過65536個(gè)鏈接呢?這得需要先了解一下系統(tǒng)是如何標(biāo)識(shí)一個(gè)網(wǎng)絡(luò)套接字(socket)的路幸。當(dāng)系統(tǒng)創(chuàng)建一個(gè)網(wǎng)絡(luò)套接字荐开,會(huì)以{源IP地址,源端口简肴,目的IP地址晃听,目的端口}這樣一個(gè)四元組來唯一表示這個(gè)鏈接。假設(shè)一個(gè)server擁有一個(gè)IP地址,而端口號(hào)最多就是65536個(gè)(極限)因此最大鏈接數(shù)也就固定了能扒。如果我們?cè)谝粋€(gè)server上維持創(chuàng)建100M個(gè)鏈接佣渴,粗略估算一個(gè)IP 60000個(gè)鏈接,我們將需要17個(gè)IP地址初斑。

開始測(cè)試

測(cè)試程序的都是用Vert.x實(shí)現(xiàn)的辛润,源碼在此。代碼是非常簡(jiǎn)單的见秤,沒必要說了砂竖。看看在測(cè)試過程中遇到的一些問題鹃答。

1.當(dāng)連接增加到23萬多的時(shí)候乎澄,服務(wù)器hang住了,不在接受任何鏈接测摔。

...
231000 connections connects in...
232000 connections connects in...

通過dmesg查看系統(tǒng)日志發(fā)了一些線索:

[13662.489289] TCP: too many orphaned sockets
[13662.489299] TCP: too many orphaned sockets
[13662.489304] TCP: too many orphaned sockets
[13662.489311] TCP: too many orphaned sockets
[13662.489317] TCP: too many orphaned sockets
[13662.489323] TCP: too many orphaned sockets
[13662.489330] TCP: too many orphaned sockets
[13662.489335] TCP: too many orphaned sockets
[13662.489341] TCP: too many orphaned sockets
[13662.489348] TCP: too many orphaned sockets

網(wǎng)上搜了一下置济,這是系統(tǒng)耗光了socket內(nèi)存,導(dǎo)致新連接進(jìn)來時(shí)無法分配內(nèi)存锋八。需要調(diào)整一下tcp socket參數(shù)浙于。在tcp_mem三個(gè)值分別代表low,pressure查库,high三個(gè)伐值。

low:當(dāng)TCP使用了低于該值的內(nèi)存頁面數(shù)時(shí)黄琼,TCP不會(huì)考慮釋放內(nèi)存樊销。
pressure:當(dāng)TCP使用了超過該值的內(nèi)存頁面數(shù)量時(shí),TCP試圖穩(wěn)定其內(nèi)存使用脏款,進(jìn)入pressure模式围苫,當(dāng)內(nèi)存消耗低于low值時(shí)則退出pressure狀態(tài)。
high:允許所有tcp sockets用于排隊(duì)緩沖數(shù)據(jù)報(bào)的頁面量撤师,當(dāng)內(nèi)存占用超過此值剂府,系統(tǒng)拒絕分配socket,后臺(tái)日志輸出"TCP: too many of orphaned sockets"剃盾。

打開/etc/sysctl.conf腺占,加入以下配置:

net.ipv4.tcp_mem = 786432 2097152 3145728 
net.ipv4.tcp_rmem = 4096 4096 6291456
net.ipv4.tcp_wmem = 4096 4096 6291456

tcp_mem 中的單位是頁,1頁=4096字節(jié)痒谴。所以我們?cè)O(shè)置的最大tcp 內(nèi)存是12G衰伯。tcp_rmem,tcp_wmem單位是byte积蔚,所以最小socket讀寫緩存是4k意鲸。

2.server 又卡住不創(chuàng)建鏈接了。

236000 connections connects in...
237000 connections connects in...
238000 connections connects in...

再次查看系統(tǒng)異常信息。

[ 1465.133062] nf_conntrack: nf_conntrack: table full, dropping packet
[ 1465.133066] nf_conntrack: nf_conntrack: table full, dropping packet
[ 1470.134845] net_ratelimit: 23807 callbacks suppressed
[ 1470.134846] nf_conntrack: nf_conntrack: table full, dropping packet
[ 1470.154131] nf_conntrack: nf_conntrack: table full, dropping packet
[ 1470.154138] nf_conntrack: nf_conntrack: table full, dropping packet
[ 1470.161674] nf_conntrack: nf_conntrack: table full, dropping packet

nf_conntrack就是linux NAT的一個(gè)跟蹤連接條目的模塊怎顾,nf_conntrack模塊會(huì)使用一個(gè)哈希表記錄TCP通訊協(xié)議的創(chuàng)建的鏈接記錄读慎,當(dāng)這個(gè)哈希表滿了的時(shí)候,便會(huì)導(dǎo)致:nf_conntrack: table full, dropping packet錯(cuò)誤槐雾。那我們接下來修改一下這個(gè)值夭委,還是打開/etc/sysctl.conf文件。
加入以下記錄:

net.netfilter.nf_conntrack_max = 1200000
net.netfilter.nf_conntrack_buckets = 150000

這兩個(gè)值表示conntrack的最大值蚜退,以及哈希的桶數(shù)闰靴。

還有一個(gè)關(guān)于JVM的調(diào)優(yōu),這個(gè)也要注意钻注,剛開始創(chuàng)建幾萬個(gè)的時(shí)候沒什么影響蚂且,但是上20萬之后GC影響逐漸顯著, 停頓次數(shù)和時(shí)間都比較顯著。我這邊server給了兩個(gè)G, client給了5個(gè)G. 調(diào)整之后好很多. 垃圾收集器CMS和Parallel都行.

參考

使用四種框架分別實(shí)現(xiàn)百萬websocket常連接的服務(wù)器
高性能網(wǎng)絡(luò)編程7--tcp連接的內(nèi)存使用
Conntrack Tuning

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幅恋,一起剝皮案震驚了整個(gè)濱河市杏死,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捆交,老刑警劉巖淑翼,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異品追,居然都是意外死亡玄括,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門肉瓦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遭京,“玉大人,你說我怎么就攤上這事泞莉∧牡瘢” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵鲫趁,是天一觀的道長斯嚎。 經(jīng)常有香客問我,道長挨厚,這世上最難降的妖魔是什么堡僻? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮疫剃,結(jié)果婚禮上苦始,老公的妹妹穿的比我還像新娘。我一直安慰自己慌申,他們只是感情好陌选,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布理郑。 她就那樣靜靜地躺著,像睡著了一般咨油。 火紅的嫁衣襯著肌膚如雪您炉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天役电,我揣著相機(jī)與錄音赚爵,去河邊找鬼。 笑死法瑟,一個(gè)胖子當(dāng)著我的面吹牛冀膝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霎挟,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼窝剖,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了酥夭?” 一聲冷哼從身側(cè)響起赐纱,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熬北,沒想到半個(gè)月后疙描,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讶隐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年起胰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巫延。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡效五,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烈评,到底是詐尸還是另有隱情火俄,我是刑警寧澤犯建,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布讲冠,位于F島的核電站,受9級(jí)特大地震影響适瓦,放射性物質(zhì)發(fā)生泄漏竿开。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一玻熙、第九天 我趴在偏房一處隱蔽的房頂上張望否彩。 院中可真熱鬧,春花似錦嗦随、人聲如沸列荔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贴浙。三九已至砂吞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間崎溃,已是汗流浹背蜻直。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留袁串,地道東北人概而。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像囱修,于是被迫代替她去往敵國和親赎瑰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 前言 關(guān)于C10K的問題就不多說了蔚袍,應(yīng)該是一個(gè)說爛的話題乡范。網(wǎng)上也有很多C1000k,甚至C10M(也就是1kw并發(fā)...
    游泳的石頭閱讀 11,018評(píng)論 3 46
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理啤咽,服務(wù)發(fā)現(xiàn)晋辆,斷路器,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 簡(jiǎn)介 用簡(jiǎn)單的話來定義tcpdump宇整,就是:dump the traffic on a network瓶佳,根據(jù)使用者...
    保川閱讀 5,941評(píng)論 1 13
  • Ubuntu的發(fā)音 Ubuntu臂拓,源于非洲祖魯人和科薩人的語言厚脉,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲de夢(mèng)閱讀 99,159評(píng)論 9 467
  • 我覺得天底下最愛惜糧食的人就是我的父親胶惰。 昨天午餐傻工,我說我為了身材苗條一些,我每餐只吃八成飽孵滞。 部隊(duì)出身的曾擔(dān)任軍...
    火山wj閱讀 83評(píng)論 0 0