• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            陳碩的Blog

            Muduo 網絡編程示例之六:限制服務器的最大并發連接數

            Muduo 網絡編程示例之六:限制服務器的最大并發連接數

            陳碩 (giantchen_AT_gmail)

            Blog.csdn.net/Solstice  t.sina.com.cn/giantchen

            這是《Muduo 網絡編程示例》系列的第六篇文章。

            Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/779646.aspx

             

            本文已以大家都熟悉的 EchoServer 介紹如何限制服務器的并發連接數。

            本文的代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/maxconnection/

            《Muduo 網絡編程示例 系列》計劃中的第六篇文章原本是“用于測試兩臺機器的帶寬的 pingpong 程序”,pingpong 協議的程序已經在《muduo 與 boost asio 吞吐量對比》和《muduo 與 libevent2 吞吐量對比》兩篇文章中介紹過了,所以我改為寫另外一個有點意思的主題。

            這篇文章中的“并發連接數”是指一個 server program 能同時支持的客戶端連接數,連接系由客戶端主動發起,服務端被動接受(accept)連接。(如果要限制應用程序主動發起的連接,則問題要簡單得多,畢竟主動權和決定權都在程序本身。)

            為什么要限制并發連接數?

            一方面,我們不希望服務程序超載,另一方面,更因為 file descriptor 是稀缺資源,如果出現 file descriptor 耗盡,很棘手(跟 “malloc 失敗/new() 拋出 std::bad_alloc”差不多同樣棘手)。

            我在《分布式系統的工程化開發方法》一文中曾談到 libev 作者建議的一種應對“accept()ing 時 file descriptor 耗盡”的辦法。

             

            幻燈片35

            幻燈片36

            Muduo 的 acceptor 正是這么實現的,但是,這個做法在多線程下不能保證正確,會有 race condition。(思考題:是什么 race condition?)

            其實有另外一種比較簡單的辦法:file descriptor 是 hard limit,我們可以自己設一個稍低一點的 soft limit,如果超過 soft limit 就主動關閉新連接,這樣就避免觸及“file descriptor 耗盡”這種邊界條件。比方說當前進程的 max file descriptor 是 1024,那么我們可以在連接數達到 1000 的時候進入“拒絕新連接”狀態,這樣留給我們足夠的騰挪空間。

             

            Muduo 中限制并發連接數


            Muduo 中限制并發連接數的做法簡單得出奇。以在《Muduo 網絡編程示例之零:前言》中出場過的 EchoServer 為例,只需要為它增加一個 int 成員,表示當前的活動連接數。(如果是多線程程序,應該用 muduo::AtomicInt32。)

            class EchoServer
            {
             public:
              EchoServer(muduo::net::EventLoop* loop,
                         const muduo::net::InetAddress& listenAddr,
                         int maxConnections);
            
              void start();
            
             private:
              void onConnection(const muduo::net::TcpConnectionPtr& conn);
            
              void onMessage(const muduo::net::TcpConnectionPtr& conn,
                             muduo::net::Buffer* buf,
                             muduo::Timestamp time);
            
              muduo::net::EventLoop* loop_;
              muduo::net::TcpServer server_;
              int numConnected_; // should be atomic_int
              const int kMaxConnections;
            };

            然后,在 EchoServer::onConnection() 中判斷當前活動連接數,如果超過最大允許數,則踢掉連接。

            void EchoServer::onConnection(const TcpConnectionPtr& conn)
            {
              LOG_INFO << "EchoServer - " << conn->peerAddress().toHostPort() << " -> "
                << conn->localAddress().toHostPort() << " is "
                << (conn->connected() ? "UP" : "DOWN");
            
              if (conn->connected())
              {
                ++numConnected_;
                if (numConnected_ > kMaxConnections)
                {
                  conn->shutdown();
                }
              }
              else
              {
                --numConnected_;
              }
              LOG_INFO << "numConnected = " << numConnected_;
            }
            

            這種做法可以積極地防止耗盡 file descriptor。

            另外,如果是有業務邏輯的服務,可以在 shutdown() 之前發送一個簡單的響應,表明本服務程序的負載能力已經飽和,提示客戶端嘗試下一個可用的 server(當然,下一個可用的 server 地址不一定要在這個響應里給出,客戶端可以自己去 name service 查詢),這樣方便客戶端快速 failover。

             

            后文將介紹如何處理空閑連接的超時:如果一個連接長時間(若干秒)沒有輸入數據,則踢掉此連接。辦法有很多種,我用 Time Wheel 解決。

            posted on 2011-04-27 00:03 陳碩 閱讀(4892) 評論(9)  編輯 收藏 引用 所屬分類: muduo

            評論

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 00:52 ouyang

            那對于TCP服務器來說,應該限制最大并發連接數為多少合適呢?另外,Muduo是否適合用來開發大并發(單機2萬+)、短連接、小流量(整體網絡流量不大)的TCP服務器?請指點。謝謝!  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 08:20 陳碩

            @ouyang
            > 限制最大并發連接數為多少合適呢?
            看應用的復雜度,看多少個并發連接就把 CPU 或者 Memory 或者 IO 占滿,然后設一個比它略小的上限,以保證服務質量。

            > Muduo是否適合用來開發大并發(單機2萬+)、短連接、小流量(整體網絡流量不大)的TCP服務器?
            應該可以,可能要為短連接適當優化一下 Acceptor。不過如果是短連接的話,單機并發 2萬+ 是指什么?同時有 2 萬個連接在線嗎?那這不是長連接嗎?  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 13:12 ouyang

            比如說可能有幾十萬上百萬個用戶,每個用戶都會連接到服務器在很短時間內(10秒內)做些數據交互,估計最大同時在線的并發數在幾萬(2-3萬)左右。不考慮其他因素(出口帶寬、服務器的內存大小)等的影響,光TCP服務器這塊,如果采用Muduo,需要做些什么特色處理嗎?謝謝!  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數[未登錄] 2011-04-27 14:54 陳碩

            @ouyang
            按照你提供的數據,并發數 30000,每個連接存活時間 10 秒,可以計算出至少每秒鐘要 accept 3000 個連接,并斷開 3000 個舊連接(假設客戶端主動斷開連接,這樣服務器不進入 time-wait 狀態)。
            對于服務端,每 accept 一個連接需要收兩個 packet,發一個 packet。
            每斷開一個連接需要收兩個 packet,發兩個 packet。
            這樣一生一滅,操作系統每秒鐘要處理 6~7 * 3000 = 18,000 ~ 21,000 個 packet。你確定你的服務器還有資源處理業務嗎?
            如果是單線程,平均每個連接的業務處理時間只有 0.3 毫秒,來得及完成任務嗎?

            對于 muduo,需要做的優化是修改 Acceptor::handleRead(),每次 accept N 個連接,而不是 1 個。N 的值可能是 10。
            見下面這篇論文第 5.2 節: http://www.cs.uwaterloo.ca/~brecht/papers/ols-2004.pdf
              回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 23:02 test

            紙上談兵吧
            不會死循環的  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 23:10 陳碩

            @test
            這位名為“test”的網友,您測過嗎?  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 23:43 test

            寫過很多類似代碼。
            超過ulimit maxfile的設置后,打印超出最大連接。 但不死循環  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-27 23:48 陳碩

            @test
            那你怎么關閉那個 pending connection ?
            抑或根本不是 level-trigger reactor?  回復  更多評論   

            # re: Muduo 網絡編程示例之六:限制服務器的最大并發連接數 2011-04-28 00:15 test

            不處理。
            現在沒有環境 也不好測試, 搜索了下, 有人說和不同內核版本號有關系。  回復  更多評論   

            <2011年2月>
            303112345
            6789101112
            13141516171819
            20212223242526
            272812345
            6789101112

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            2022年国产精品久久久久| 亚洲AV无码久久精品狠狠爱浪潮 | 日本精品久久久中文字幕| 久久国产精品无码一区二区三区| 少妇久久久久久被弄到高潮| 久久精品无码专区免费青青| 国产亚洲精久久久久久无码| 91精品国产色综久久| 久久久一本精品99久久精品88| 亚洲国产精品一区二区久久hs| 国产产无码乱码精品久久鸭| 91久久精品国产成人久久| 亚洲精品白浆高清久久久久久| …久久精品99久久香蕉国产 | 亚洲精品乱码久久久久久蜜桃图片| 奇米影视7777久久精品| 国产精品久久久久久久久久影院 | 亚洲精品国产字幕久久不卡| 久久精品视屏| 久久只有这精品99| 久久中文字幕视频、最近更新| 久久免费小视频| 久久久青草久久久青草| 国产精品一区二区久久精品| 麻豆一区二区99久久久久| 色婷婷综合久久久久中文字幕 | 国产精品99久久不卡| 久久久中文字幕| 日韩影院久久| 亚洲香蕉网久久综合影视| 亚洲国产一成人久久精品 | 精品人妻伦九区久久AAA片69| 日本免费一区二区久久人人澡| 久久精品国产精品青草| 国产叼嘿久久精品久久| 国产精品久久久久久久久软件| 国产成人精品综合久久久久| 欧美激情精品久久久久| 2020久久精品亚洲热综合一本| 97久久国产亚洲精品超碰热| 久久综合精品国产一区二区三区|