聶永的博客

          記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

          100萬(wàn)并發(fā)連接服務(wù)器筆記之準(zhǔn)備篇

          前言

          測(cè)試一個(gè)非常簡(jiǎn)單服務(wù)器如何達(dá)到100萬(wàn)(1M=1024K連接)的并發(fā)連接,并且這些連接一旦連接上服務(wù)器,就不會(huì)斷開(kāi),一直連著。
          環(huán)境受限,沒(méi)有服務(wù)器,剛開(kāi)始都是在自己的DELL筆記本上測(cè)試,憑借16G內(nèi)存,和優(yōu)秀的vmware workstation虛擬機(jī)配合,另外還得外借別人虛擬機(jī)使用,最終還得搭上兩臺(tái)2G內(nèi)存的臺(tái)式機(jī)(安裝centos),最終才完成1M并發(fā)連接任務(wù)。

          • 測(cè)試程序也很簡(jiǎn)陋,一個(gè)C語(yǔ)言所寫(xiě)服務(wù)器程序,沒(méi)有任何業(yè)務(wù)存在,收到請(qǐng)求后發(fā)送一些頭部,不斷開(kāi)連接
          • 測(cè)試端程序也是使用C語(yǔ)言所寫(xiě),發(fā)送請(qǐng)求,然后等待接收數(shù)據(jù),僅此而已
          • 服務(wù)器端/測(cè)試端內(nèi)存都受限(8G不夠使用),要想完成1024K的目標(biāo),需要放棄一些東西,諸如業(yè)務(wù)不是那么完整
          • 一臺(tái)分配10G內(nèi)存Centos服務(wù)器,兩臺(tái)分配6G內(nèi)存Centos測(cè)試端,兩臺(tái)2G內(nèi)存Centos測(cè)試端
          • 假如熱心的您可以提供豐富的服務(wù)器資源,那就再好不過(guò)了。
          • 理論上200萬(wàn)的并發(fā)連接(IO密集型),加上業(yè)務(wù),40G-50G的內(nèi)存大概能夠保證

          說(shuō)明

          以前也做過(guò)類似的工作,量不大,沒(méi)記錄下來(lái),一些壓力測(cè)試和調(diào)優(yōu),隨著時(shí)間流逝,早已忘記。這次是從零開(kāi)始,基本上所有過(guò)程都會(huì)記錄,一步一步,每一步都會(huì)遇到問(wèn)題,并且給出相關(guān)解決問(wèn)題的方法,最終完成目標(biāo)。
          為了方便,服務(wù)器端程序和客戶端測(cè)試程序,都是使用C語(yǔ)言,不用像JAVA一樣需要預(yù)先指定內(nèi)存,感覺(jué)麻煩。使用較為原始的語(yǔ)言來(lái)寫(xiě),可以避免不必要的調(diào)優(yōu)工作。這中間,可能會(huì)穿插Java代碼的思考方式。

          可能需要懂點(diǎn)Linux,C,Java,假如您有更好的做法,或者建議,請(qǐng)直接告知,謝謝。

          Linux系統(tǒng)

          測(cè)試端和服務(wù)器端都選用較為熟悉的64位Centos 6.4,32位系統(tǒng)最多支持4G內(nèi)存,太受限。IO密集型應(yīng)用,對(duì)CPU要求不是很高。另外服務(wù)器確保安裝上gcc,那就可以開(kāi)工了。
          所有端系統(tǒng)一旦安裝完之后,默認(rèn)不做任何設(shè)置。

          服務(wù)器端程序

          服務(wù)器端程序依賴libev框架,需要提前編譯,然后存放到相應(yīng)位置。下面是具體服務(wù)器端代碼:

          編譯

          gcc server.c -o server ../include/libev.a -lm
          

          運(yùn)行

          ./server -p 8000
          

          在源碼中默認(rèn)指定了8000端口,可以通過(guò)-p進(jìn)行指定新的端口。 開(kāi)啟了8000端口進(jìn)行監(jiān)聽(tīng)請(qǐng)求,http協(xié)議處理類似于htmlfile chunked塊編碼傳輸。

          測(cè)試服務(wù)器端程序

          測(cè)試程序使用libevent框架,因其使用簡(jiǎn)單,提供豐富易用接口,但需要提前下載,手動(dòng)安裝:

          wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
          tar xvf libevent-2.0.21-stable.tar.gz
          cd libevent-2.0.21-stable
          ./configure --prefix=/usr
          make
          make install
          

          注意make和make install需要root用戶。

          測(cè)試端程序

          client1.c 源碼:

          備注:這部分代碼參考了A Million-user Comet Application with Mochiweb, Part 3 ,根據(jù)需要有所修改。

          編譯

          gcc -o client1 client1.c -levent
          

          運(yùn)行

          ./client1
          

          可能在64位系統(tǒng)會(huì)遇到找不到libevent-2.0.so.5情況,需要建立一個(gè)軟連接

          ln -s /usr/lib/libevent-2.0.so.5 /lib64/libevent-2.0.so.5
          

          即可自動(dòng)連接IP地址為192.168.190.133:8000的服務(wù)器端應(yīng)用。

          第一個(gè)遇到的問(wèn)題:文件句柄受限

          測(cè)試端程序輸出

          看看測(cè)試端程序client1輸出的錯(cuò)誤信息:

          Chunks: 798 Bytes: 402990 Closed: 0
          Req: 192.168.190.133 -/test/900
          Req: 192.168.190.133 -/test/1000
          Chunks: 998 Bytes: 503990 Closed: 0
          [warn] socket: Too many open files
          [warn] socket: Too many open files
          [warn] socket: Too many open files
          

          服務(wù)器端程序輸出

          服務(wù)器端最后一條日志為

          online user 1018
          

          兩邊都遇到了文件句柄打開(kāi)的情況。
          在服務(wù)器端查看已經(jīng)連接,并且端口號(hào)為8000的所有連接數(shù)量:

          netstat -nat|grep -i "8000"|wc -l 
          1019

          但與服務(wù)器端輸出數(shù)量對(duì)不上,增加所有已經(jīng)建立連接的選項(xiàng):

          netstat -nat|grep -i "8000"|grep ESTABLISHED|wc -l 
          1018

          那么剩下的一條數(shù)據(jù)到底是什么呢?

          netstat -nat|grep -i "8000"|grep -v ESTABLISHED
          tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 

          也就是server.c監(jiān)聽(tīng)的端口,數(shù)量上對(duì)的上。

          在測(cè)試服務(wù)器端,查看測(cè)試進(jìn)程打開(kāi)的文件句柄數(shù)量

          lsof -n|grep client1|wc -l
          1032
          

          再次執(zhí)行

          ulimit -n
          1024
          

          也是就是client1應(yīng)用程序共打開(kāi)了1032個(gè)文件句柄,而不是1024,為什么?
          把當(dāng)前進(jìn)程所有打開(kāi)的文件句柄保存到文件中,慢慢研究 lsof -n|grep client1 > testconnfinfo.txt

          導(dǎo)出的文件可以參考: https://gist.github.com/yongboy/5260773
          除了第一行,我特意添加上供友善閱讀的頭部列定義,也就是1032行信息,但是需要注意頭部:

          
          COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
          client1 3088 yongboy cwd DIR 253,0 4096 800747 /home/yongboy/workspace/c_socket.io_server/test
          client1 3088 yongboy rtd DIR 253,0 4096 2 /test_conn
          client1 3088 yongboy txt REG 253,0 9697 799991 /home/yongboy/workspace/c_socket.io_server/test/test_conn_1
          client1 3088 yongboy mem REG 253,0 156872 50404 /lib64/ld-2.12.so
          client1 3088 yongboy mem REG 253,0 1922152 78887 /lib64/libc-2.12.so
          client1 3088 yongboy mem REG 253,0 145720 76555 /lib64/libpthread-2.12.so
          client1 3088 yongboy mem REG 253,0 47064 69491 /lib64/librt-2.12.so
          client1 3088 yongboy mem REG 253,0 968730 26292 /usr/lib/libevent-2.0.so.5.1.9
          client1 3088 yongboy 0u CHR 136,2 0t0 5 /dev/pts/2
          client1 3088 yongboy 1u CHR 136,2 0t0 5 /dev/pts/2
          client1 3088 yongboy 2u CHR 136,2 0t0 5 /dev/pts/2
          client1 3088 yongboy 3u REG 0,9 0 4032 anon_inode
          client1 3088 yongboy 4u unix 0xffff88007c82f3c0 0t0 79883 socket
          client1 3088 yongboy 5u unix 0xffff880037c34380 0t0 79884 socket
          client1 3088 yongboy 6u IPv4 79885 0t0 TCP 192.168.190.134:58693->192.168.190.133:irdmi (ESTABLISHED)
          client1 3088 yongboy 7u IPv4 79889 0t0 TCP 192.168.190.134:58694->192.168.190.133:irdmi (ESTABLISHED)
          client1 3088 yongboy 8u IPv4 79891 0t0 TCP 192.168.190.134:58695->192.168.190.133:irdmi (ESTABLISHED)
          client1 3088 yongboy 9u IPv4 79893 0t0 TCP 192.168.190.134:58696->192.168.190.133:irdmi (ESTABLISHED)
          

          可以看到文件句柄是從0u開(kāi)始,0u上面的8個(gè)(5個(gè)mem + 3個(gè)啟動(dòng))進(jìn)程,1032 - 8 = 1024個(gè)文件句柄,這樣就和系統(tǒng)限制的值吻合了。

          root用戶編輯/etc/security/limits.conf文件添加:

          * soft nofile 1048576
          * hard nofile 1048576
          
          • soft是一個(gè)警告值,而hard則是一個(gè)真正意義的閥值,超過(guò)就會(huì)報(bào)錯(cuò)。
          • soft 指的是當(dāng)前系統(tǒng)生效的設(shè)置值。hard 表明系統(tǒng)中所能設(shè)定的最大值
          • nofile - 打開(kāi)文件的最大數(shù)目
          • 星號(hào)表示針對(duì)所有用戶,若僅針對(duì)某個(gè)用戶登錄ID,請(qǐng)?zhí)鎿Q星號(hào)

          注意:
          1024K x 1024 = 1048576K = 1M,1百萬(wàn)多一點(diǎn)。

          備注:測(cè)試端和服務(wù)器端都需要作此設(shè)置,保存退出,然后reboot即可生效。

          第一個(gè)問(wèn)題,就這樣克服了。再次運(yùn)行 /client1測(cè)試程序,就不會(huì)出現(xiàn)受打開(kāi)文件句柄的限制。但大概在測(cè)試端打開(kāi)對(duì)外28200個(gè)端口時(shí),會(huì)出現(xiàn)程序異常,直接退出。

          段錯(cuò)誤

          這個(gè)也是程序沒(méi)有處理端口不夠用的異常,但可以通過(guò)增加端口進(jìn)行解決。

          備注: 但測(cè)試端單機(jī)最多只能打開(kāi)6萬(wàn)多個(gè)連接,是一個(gè)問(wèn)題,如何克服,下一篇解決此問(wèn)題,并且還會(huì)遇到文件句柄的受限問(wèn)題。

          posted on 2013-04-09 09:50 nieyong 閱讀(17138) 評(píng)論(3)  編輯  收藏 所屬分類: C1M

          評(píng)論

          # re: 100萬(wàn)并發(fā)連接服務(wù)器筆記之準(zhǔn)備篇 2015-05-29 22:14 wander

          想問(wèn)下博主的,模擬多客戶端測(cè)試怎么實(shí)現(xiàn)的
            回復(fù)  更多評(píng)論   

          # re: 100萬(wàn)并發(fā)連接服務(wù)器筆記之準(zhǔn)備篇 2015-06-01 13:58 nieyong

          @wander
          可以參考:
          http://www.aygfsteel.com/yongboy/archive/2013/04/09/397594.html
          http://www.aygfsteel.com/yongboy/archive/2013/04/10/397631.html
          這兩篇文章 :)  回復(fù)  更多評(píng)論   

          # re: 100萬(wàn)并發(fā)連接服務(wù)器筆記之準(zhǔn)備篇 2015-10-13 16:36 godsoul

          博主,client1.c 源碼在哪里,能分享一下嗎,你說(shuō)修改老外那篇,不知道修改了哪里  回復(fù)  更多評(píng)論   

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請(qǐng)標(biāo)明出處,謝謝~

          新浪微博,歡迎關(guān)注:

          導(dǎo)航

          <2015年6月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          統(tǒng)計(jì)

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個(gè)人收藏

          最新隨筆

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 洞头县| 石楼县| 旌德县| 兰考县| 阿拉尔市| 凤山县| 凤台县| 巢湖市| 普洱| 萝北县| 永兴县| 隆子县| 乌审旗| 伊金霍洛旗| 万源市| 措美县| 潮州市| 沈丘县| 利川市| 南江县| 尤溪县| 肃宁县| 同仁县| 桑植县| 昌乐县| 札达县| 龙口市| 卢湾区| 尼木县| 遂溪县| 满城县| 凤冈县| 保定市| 武平县| 北海市| 中西区| 海林市| 建德市| 铁力市| 肇东市| 七台河市|