很長一段時間對web模型的併發量的理解只是停留在單臺併發在5萬左右 ,具體爲何這樣,理解的並不深入,只是在看nginx的相關文檔時都這樣介紹的。後來在處理個信的推送(comet應用)時,對於其單臺上百萬的鏈接甚是不解。感受這違背了單臺5萬併發的邏輯。後通過梳理,找到了一個合理的解釋,後來和不少人聊到單臺主機的併發問題時,發現不少人都存在這個誤區,目前總結以下。理解不對的地方,也歡迎板磚。php
如上圖所示是一個典型的web模型:前端
單臺併發在5萬左右,能夠先理解爲單臺client 的併發在50000左右。衆所周知,一臺主機的可用端口範圍是1-65535 ,除掉1-1024這些已定義的端口,再考慮到tcp/ip參數等其餘的一些因素。一臺主機的可用端口範圍是10000-60000之間。上圖中client到server之間的鏈接圖能夠看出:client 鏈接web服務器端時,client 的單臺併發是50000左右。其鏈接模式爲:java
10000 ---- 8010001 ---- 8010002 ---- 80…………………………
固然,單臺client也並非沒法超越這個限制,當單臺主機有多個IP時,這個限制就變成了 5w * n(ip數),其鏈接模式爲:python
192.168.1.10:10000 ---- www.361way.com:80192.168.1.10:10001 ---- www.361way.com:80192.168.1.10:10002 ---- www.361way.com:80……………………………………………………192.168.1.20:10000 ---- www.361way.com:80192.168.1.20:10001 ---- www.361way.com:80192.168.1.20:10002 ---- www.361way.com:80……………………………………………………
根據上面client -- server 的模型來看,server端並無端口不夠用的問題,因此其理論上來說也並不存在併發只侷限在5萬個的問題。因此單臺server 主機百萬併發鏈接現然也是現實的(長鏈接推送模型)。而在實際的應用中,server 端也是存在五萬併發的問題的,這裏先不考慮其餘的因素,咱們先看後一部分圖就能夠很好的解釋這個問題了。nginx
實際應用中,大部分站點都是基於動態web技術的(java、php、ASP、python、ruby等),在動態應用中,咱們通常並不會直接讓client端請求到後端就用,以tomcat爲例,雖然 client --- tomcat 是能夠正常訪問的,不過通常咱們會經過反向代理的方式訪問tomcat ,其請求爲 client ---- nginx/apache等 ------ tomcat 。這裏又變成了上面 client五萬併發的問題 ,上圖中的web server 變成了client ,app server成了server ,web server在使用完成了10000 -- 60000 之間的端口後,並有端口可用時便沒法再與後端的 app server之間創建起新的鏈接。因此前端的nginx/apache 也變成了存在5萬併發的問題。web
若是在單臺主機上配置多個IP,理論上併發數能夠達到5w * n個 。這裏具體能夠參考「網絡四元組/網絡五元組」:apache
四元組是指的是:編程
{源IP地址,源端口,目的IP地址,目的端口}
五元組指的是(多了協議):後端
{源IP地址,目的IP地址,協議號,源端口,目的端口}
在《UNIX網絡編程卷1:套接字聯網API(第3版)》一書中,是這樣解釋:tomcat
一個TCP鏈接的套接字對(socket pari)是一個定義該鏈接的兩個端點的四元組,即本地IP地址、本地TCP端口號、外地IP地址、外地TCP端口號。套接字對惟一標識一個網絡上的每一個TCP鏈接。......標識每一個端點的兩個值(IP地址和端口號)一般稱爲一個套接字。
以四元組爲例,請求的IP地址和目的端口基本上是固定的,不會變化,那麼只能從本機IP地址和本機端口上考慮,端口的範圍一旦指定了,那麼增長IP地址,能夠增長對外發出的請求數量。假設系統可使用的端口範圍已經如上所設,那麼可使用的大體端口爲64000個,系統添加了10個IP地址,那麼能夠對外發出的數量爲 64000 * 10 = 640000,數量很可觀。
以常見的1000M網卡爲例,假設請求的爲一個最簡單web頁面,頁面大小爲15KB(當前使用的富文本估計通常都會比這個大很多),1000 * 1024 /8 /15 約等於8533個鏈接 。也就是併發達到這個值就就把網卡流量跑滿了 。若是使用的是10Gb網卡,單臺的最大併發也就是8w多個。
5W * 3600 * 24 =432000W ,一天下來會有43億2千萬個鏈接(PV) 。咱們再打個折,按照請求的峯值與非峯值的二八定律及鏈接的釋放時間等,打個20倍的折,折後的值也有2億多個PV 。通達到這個量也算是不小的站了。
長鏈接推送模型中,大部分的時候只是鏈接的維持,在沒有推送任務的狀況下,鏈接之間幾乎不存在數據傳輸。因此網卡能吃的消。 另外nofile的值在2.6.25以前定義了這個值的最大值,爲1024*1024,正好是100萬,而在2.6.25內核及其以後,這個值是能夠經過/proc/sys/fs/nr_open來設置。