<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學習的點點滴滴。

    100萬并發連接服務器筆記之處理端口數量受限問題

    第二個遇到的問題:端口數量受限

    一般來說,單獨對外提供請求的服務不用考慮端口數量問題,監聽某一個端口即可。但是向提供代理服務器,就不得不考慮端口數量受限問題了。當前的1M并發連接測試,也需要在客戶端突破6萬可用端口的限制。

    單機端口上限為65536

    端口為16進制,那么2的16次方值為65536,在linux系統里面,1024以下端口都是超級管理員用戶(如root)才可以使用,普通用戶只能使用大于1024的端口值。
    系統提供了默認的端口范圍:

    cat /proc/sys/net/ipv4/ip_local_port_range
    32768 61000

    大概也就是共61000-32768=28232個端口可以使用,單個IP對外只能發送28232個TCP請求。
    以管理員身份,把端口的范圍區間增到最大:

    echo "1024 65535"> /proc/sys/net/ipv4/ip_local_port_range

    現在有64511個端口可用.
    以上做法只是臨時,系統下次重啟,會還原。 更為穩妥的做法是修改/etc/sysctl.conf文件,增加一行內容

    net.ipv4.ip_local_port_range= 1024 65535

    保存,然后使之生效:

    sysctl -p

    現在可以使用的端口達到64510個(假設系統所有運行的服務器是沒有占用大于1024的端口的,較為純凈的centos系統可以做到),要想達到50萬請求,還得再想辦法。

    增加IP地址

    一般假設本機網卡名稱為 eth0,那么手動再添加幾個虛擬的IP:

    ifconfig eth0:1 192.168.190.151
    ifconfig eth0:2 192.168.190.152 ......

    或者偷懶一些:

    for i in `seq 1 9`; do ifconfig eth0:$i 192.168.190.15$i up ; done

    這些虛擬的IP地址,一旦重啟,或者 service network restart 就會丟失。

    為了模擬較為真實環境,在測試端,手動再次添加9個vmware虛擬機網卡,每一個網卡固定一個IP地址,這樣省去每次重啟都要重新設置的麻煩。

    192.168.190.134
    192.168.190.143
    192.168.190.144
    192.168.190.145
    192.168.190.146
    192.168.190.147
    192.168.190.148
    192.168.190.149
    192.168.190.150
    192.168.190.151

    在server服務器端,手動添加橋接網卡和NAT方式網卡

    192.168.190.230
    192.168.190.240
    10.95.20.250
    

    要求測試端和服務器端彼此雙方都是可以ping通。

    網絡四元組/網絡五元組

    四元組是指的是

    {源IP地址,源端口,目的IP地址,目的端口}

    五元組指的是(多了協議)

    {源IP地址,目的IP地址,協議號,源端口,目的端口}

    在《UNIX網絡編程卷1:套接字聯網API(第3版)》一書中,是這樣解釋:
    一個TCP連接的套接字對(socket pari)是一個定義該連接的兩個端點的四元組,即本地IP地址、本地TCP端口號、外地IP地址、外地TCP端口號。套接字對唯一標識一個網絡上的每個TCP連接。

    ......

    標識每個端點的兩個值(IP地址和端口號)通常稱為一個套接字。

    以下以四元組為準。在測試端四元組可以這樣認為:

    {本機IP地址,本機端口,目的IP地址,目的端口}

    請求的IP地址和目的端口基本上是固定的,不會變化,那么只能從本機IP地址和本機端口上考慮,端口的范圍一旦指定了,那么增加IP地址,可以增加對外發出的請求數量。假設系統可以使用的端口范圍已經如上所設,那么可以使用的大致端口為64000個,系統添加了10個IP地址,那么可以對外發出的數量為 64000 * 10 = 640000,數量很可觀。

    只有{源IP地址,源端口}確定對外TCP請求數量

    經測試,四元組里面,只有{源IP地址,源端口}才能夠確定對外發出請求的數量,跟{目的IP地址,目的端口}無關。

    測試環境

    在server端,并且啟動./server兩次,分別綁定8000端口和9000端口

    ./server -p 8000
    ./server -p 9000
    

    本機IP、端口綁定測試程序

    這里寫一個簡單的測試綁定本機IP地址和指定端口的客戶端測試程序。

    可以看到libevent-*/include/event2/http.h內置了對綁定本地IP地址的支持:

    /** sets the ip address from which http connections are made */
    void evhttp_connection_set_local_address(struct evhttp_connection *evcon,
    const char *address);
    

    不用擔心端口,系統自動自動隨機挑選,除非需要特別指定:

    /** sets the local port from which http connections are made */
    void evhttp_connection_set_local_port(struct evhttp_connection *evcon,
    ev_uint16_t port);
    

    編譯

    gcc -o client3 client3.c -levent
    

    client3運行參數為

    • -h 遠程主機IP地址
    • -p 遠程主機端口
    • -c 本機指定的IP地址(必須可用)
    • -o 本機指定的端口(必須可用)

    測試用例,本機指定同樣的IP地址和端口,但遠程主機和IP不一樣.
    在一個測試端打開一個終端窗口1,切換到 client3對應位置

    ./client3 -h 192.168.190.230 -p 8000 -c 192.168.190.148 -o 4000
    

    輸出為

    remote host is 192.168.190.230
    remote port is 8000
    local ip is 192.168.190.148
    local port is 4000
    >Chunks: 1 Bytes: 505
    

    再打開一個測試端終端窗口2,執行:

    ./client3 -h 192.168.190.240 -p 9000 -c 192.168.190.148 -o 4000
    

    窗口2程序,無法執行,自動退出。
    接著在窗口2終端繼續輸入:

    ./client3 -h 192.168.190.230 -p 8000 -c 192.168.190.148 -o 4001
    

    注意,和窗口1相比,僅僅改變了端口號為4001。但執行結果,和端口1輸出一模一樣,在等待接收數據,沒有自動退出。

    剩下的,無論怎么組合,怎么折騰,只要一對{本機IP,本機端口}被占用,也就意味著對應一個具體的文件句柄,那么其它程序將不能夠再次使用。

    Java怎么綁定本地IP地址?

    java綁定就很簡單,但有些限制,不夠靈活,單純從源碼中看不出來,api doc可以告訴我們一些事情。 打開JDKAPI1_6zhCN.CHM,查看InetSocketAddress類的構造函數說明:

    public InetSocketAddress(InetAddress addr, int port)
    根據 IP 地址和端口號創建套接字地址。 有效端口值介于 0 和 65535 之間。端口號 zero 允許系統在 bind 操作中挑選暫時的端口。

    null 地址將分配通配符 地址。

    參數:
    addr - IP 地址
    port - 端口號
    拋出:
    IllegalArgumentException - 如果 port 參數超出有效端口值的指定范圍。


    public InetSocketAddress(String hostname, int port)
    根據主機名和端口號創建套接字地址。
    嘗試將主機名解析為 InetAddress。如果嘗試失敗,則將地址標記為未解析。

    如果存在安全管理器,則將主機名用作參數調用其 checkConnect 方法,以檢查解析它的權限。這可能會導致 SecurityException 異常。

    有效端口值介于 0 和 65535 之間。端口號 zero 允許系統在 bind 操作中挑選暫時的端口。

    參數: hostname - 主機名
    port - 端口號
    拋出:
    IllegalArgumentException - 如果 port 參數超出有效端口值的范圍,或者主機名參數為 null。
    SecurityException - 如果存在安全管理器,但拒絕解析主機名的權限。
    另請參見:
    isUnresolved()

    InetSocketAddress的兩個構造函數都支持,看情況使用。注意int port傳遞值為0,即可做到系統隨機挑選端口。追蹤一下源代碼,發現最終調用

    private native void socketBind(InetAddress address, int port) throws IOException;
    

    如何查看socketBind的原始C代碼,我就不清楚了,您若知曉,希望指教一下。 構造一個InetSocketAddress對象:

    SocketAddress localSocketAddr = new InetSocketAddress("192.168.190.143", 0);
    

    然后傳遞給需要位置即可。諸如使用netty連接到某個服務器上,在connect時指定遠方地址,以及本機地址

    ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) Attempts a new connection with the specified remoteAddress and the specified localAddress.

    Netty 客戶端連接API見:

    Linux支持綁定本機IP、端口原理

    說是原理,有些牽強,因為linux C提供了如何綁定函數,框架或者高級語言再怎么封裝,在linux平臺下面,需要這么調用:

    struct sockaddr_in clnt_addr;
    ....
    clnt_addr.sin_family = AF_INET;
    clnt_addr.sin_addr.s_addr = INADDR_ANY; //綁定本機IP地址
    clnt_addr.sin_port = htons(33333); //綁定本機端口
    if (bind(sockfd, (struct sockaddr *) &clnt_addr,
    sizeof(clnt_addr)) < 0) error("ERROR on binding");
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting");
    .......
    

    構造一個clnt_addr結構體,本地IP或者端口賦值,在connect之前,先bind,就這么簡單。

    更完整例子,可以參考 http://stackoverflow.com/questions/4852256/need-a-complete-snippet-example-of-binding-tcp-client-socket

    有關端口的更詳細解釋,請參考《UNIX網絡編程卷1:套接字聯網API(第3版)》2.9節 端口號部分。

     

    有關端口的問題,到此為止,下一篇,回到測試。

    posted on 2013-04-09 17:26 nieyong 閱讀(18428) 評論(0)  編輯  收藏 所屬分類: C1M

    公告

    所有文章皆為原創,若轉載請標明出處,謝謝~

    新浪微博,歡迎關注:

    導航

    <2013年4月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    統計

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 美景之屋4在线未删减免费 | 伊人久久大香线蕉免费视频| 在线jlzzjlzz免费播放| 亚洲精品国产手机| 99精品视频在线免费观看| 老汉色老汉首页a亚洲| 免费播放一区二区三区| 亚洲无线电影官网| 无人在线直播免费观看| 亚洲 暴爽 AV人人爽日日碰| 好爽…又高潮了免费毛片| 亚洲国产成人手机在线观看| 日韩精品视频免费在线观看| 直接进入免费看黄的网站| 亚洲精品无码久久不卡| 国产精品综合专区中文字幕免费播放| 在线亚洲人成电影网站色www| 久久国产免费观看精品| 亚洲熟妇无码久久精品| 性感美女视频在线观看免费精品| 欧洲亚洲国产精华液| 亚洲日韩在线第一页| 免费无码又爽又刺激高潮视频| 青青草原精品国产亚洲av| 人禽杂交18禁网站免费| 美景之屋4在线未删减免费 | 亚洲成a人片在线观看老师| 中文字幕无线码免费人妻| 亚洲天堂在线播放| 免费看少妇作爱视频| 国产精品免费看久久久香蕉| 久久狠狠高潮亚洲精品| 日本a级片免费看| 一个人免费视频观看在线www| 亚洲成人一级电影| 免费v片视频在线观看视频| 日韩电影免费在线观看| 亚洲日韩精品A∨片无码加勒比| 亚洲宅男天堂在线观看无病毒| 久久福利资源网站免费看| 一区二区免费电影|