我相信,不少人都跟我同樣,看書都不會太細緻也不太認真思考,感受書中講的東西都應該是對的,最近讀書時我發現之前認爲理所固然的東西事實上壓根都沒有弄明白,最終的結果是,書是別人的,書中的知識也是別人的。html
不管是看過的nginx有關書仍是網上看到的有關nginx 配置說明的文章(http://wiki.nginx.org/EventsModule#worker_connections),無一例外,在講到 worker_connections 和 max_clients這兩個概念的關係時都一致的一筆帶過,尤爲是在講到nginx做爲反向代理時max_clients的計算時,都是想固然的貼出max_clients = worker_processes * worker_connections/4這個理論計算公式來。既然是理論公式,那麼爲何要除以4呢?確定是有緣由的吧。我相信有些人是知道如何計算的,可是不少人都如我同樣一眼掃過,真正等到別人或者本身問本身的時候就真的感受是雲裏霧裏,不知因此然了。nginx
我認爲,要搞清楚這個公式是否正確,以及如何計算的,那首先要對nginx的各個配置說明有清晰的認識:web
nginx做爲http服務器的時候:後端
max_clients = worker_processes * worker_connections瀏覽器
nginx做爲反向代理服務器的時候:bash
max_clients = worker_processes * worker_connections/4服務器
咱們暫且不來斷定這兩個公式是否正確,我曾經認爲nginx做爲反向代理,要同時維持客戶端和後端被代理server兩個連接應該是除以2而不是除以4,後來想到鏈接請求都是雙向的,也就認爲除以4應該是正確的。固然,我想的極有多是不正確的,個人判斷是否正確最終仍是須要咱們根據每個參數的實際含義來判斷(固然,能夠很明確的告訴你,個人想法是錯誤的。至於緣由呢,後面告訴你。)。仍是讓咱們一塊兒來看下max_clients,worker_processes和worker_connections的官方說明,對其所包含的含義搞清楚明白,再來肯定之間的關係。併發
worker_processes:app
官方英文版wiki配置說明中的描述以下,我的理解爲worker角色的進程個數(nginx啓動後有多少個worker處理http請求。master不處理請求,而是根據相應配置文件信息管理worker進程. master進程主要負責對外攬活(即接收客戶端的請求),並將活兒合理的分配給多個worker,每一個worker進程主要負責幹活(處理請求))。運維
syntax:worker_processes number | auto; default: worker_processes 1; context:main Defines the number of worker processes.
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
root 3153 1 0 12:11 ? 00:00:00 nginx: master process
nobody 3154 3153 0 12:11 ? 00:00:00 nginx: worker process nobody 3155 3153 0 12:11 ? 00:00:00 nginx: worker process
nobody 3156 3153 0 12:11 ? 00:00:00 nginx: worker process
nobody 3157 3153 0 12:11 ? 00:00:00 nginx: worker process
The optimal value depends on many factors including (but not limited to) the number of CPU cores, the number of hard disk drives that store data, and load pattern. When one is in doubt, setting it to the number of available CPU cores would be a good start (the value 「auto」 will try to autodetect it).
The auto parameter is supported starting from versions 1.3.8 and 1.2.5.
最理想的worker_processes值取決於不少因素,包含但不限於CPU的核數,存儲數據的硬盤驅動器個數(跟這個有什麼關係?難道和cpu同樣,存在跨區域讀取數據問題),以及負載模式(?這個是什麼?)當其中任何一個因素不肯定的時候,將其設置爲cpu核數或許是一個比較好的初始值,「自動」也基本是如此確認一個參數值的。
「自動」這個參數值是從nginx 1.3.8和nginx 1.2.5 開始進行支持的,自動參數能夠自動檢測 cpu cores 並設置 worker_processes 參數 。
在網上也看到如下建議:
nginx doesn't benefit from more than one worker per CPU.
一個cpu配置多於一個worker數,對nginx而言沒有任何益處。
If Nginx is doing CPU-intensive work such as SSL or gzipping and you have 2 or more CPUs/cores, then you may set worker_processes to be equal to the number of CPUs or cores.
若是nginx處理的是cpu密集型(比較耗費cpu的)的操做,建議將此值設置爲cpu個數或cpu的核數。
worker_connections:
官方解釋以下,我的認爲是每個worker進程能併發處理(發起)的最大鏈接數(包含全部鏈接數)。
syntax:worker_connections number; default: worker_connections 512; context:events
Sets the maximum number of simultaneous(併發) connections that can be opened by a worker process.
It should be kept in mind(謹記) that this number includes all connections (e.g. connections with proxied servers(與被代理服務之間的鏈接數), among others(與其餘角色之間的)), not only connections with clients(不只僅是與客戶端之間的鏈接數). Another consideration is that the actual(實際的) number of simultaneous connections cannot exceed(超過) the current limit(當前限制) on the maximum number of open files(最大文件打開數), which can be changed by worker_rlimit_nofile (能夠在worker_rlimit_nofile中改變的參數).
worker_rlimit_nofile xxxxx;
context:events
####Specifies(指定) the value for maximum file descriptors(可被一個工做進程打開的最大文件描述符數量) that can be opened by this process.
注意:設置了這個後,修改worker_connections值時,是不能超過worker_rlimit_nofile的這個值。
max_clients:
這個參數沒有出如今nginx的配置文件中,我也沒在官方的文檔中找到這個參數,可是不少的文章和書籍都提到了這個參數。有不少人將這個翻譯爲最大訪問客戶數,我的認爲沒有什麼不妥的,所以咱們就當這個是nginx在理論狀況下能處理的最大訪問客戶數,固然這個客戶數不是具體的用戶。
當nginx做爲http 靜態內容的web服務器時,只須要處理來自客戶端的鏈接請求便可(請求是雙向的,鏈接是沒有方向的,因此我上面說的反向代理是鏈接雙向,除以4的說法是不正確的)。
由HTTP客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP鏈接。HTTP服務器則在那個端口監聽客戶端的請求。一旦收到請求,服務器會向客戶端返回一個狀態,好比"HTTP/1.1 200 OK",以及返回的內容,如請求的文件、錯誤消息、或者其它信息。同一時刻nginx在處理客戶端發送的http請求應該只是一個connection,由此可知理論上做爲http web服務器角色的nginx可以處理的最大鏈接數就是最大客戶端鏈接數。
所以理論上的最大客戶端鏈接數計算公式爲:
max_clients = worker_processes * worker_connections;
那一直讓我犯迷糊的問題,nginx做爲反向代理時能夠處理的最大客戶鏈接數是如何計算的呢?
若是隻是簡單的按照http server服務器的計算模式,加上nginx將用戶請求轉向被代理服務器時創建的鏈接,最大的客戶鏈接數也應該仍是我以前理解的,在nginx做爲http服務器的最大客戶端鏈接數的基礎上除以2了。固然,事實上很可能和我想象的不同了。
官方wiki(頁面標記已通過時,可是網上不少文章都在引用)看到一個關於爲何除以4的解釋:
若是做爲反向代理,由於瀏覽器默認會開啓2個鏈接到server,並且Nginx還會使用fds(file descriptor)從同一個鏈接池創建鏈接到upstream後端。則最大鏈接數的計算公式以下:
max_clients = worker_processes * worker_connections / 4;
Since(由於) a browser opens 2 connections by default to a server and nginx uses the fds (file descriptors) from the same pool to connect to the upstream backend。
我有兩個疑問:
瀏覽器怎麼知道nginx是做爲反向代理的?nginx 響應中會有說明?
若是瀏覽器知道nginx是做爲反向代理的,那爲何須要開啓2個鏈接到server,並且這根使用文件描述符從同一個鏈接池(這又是什麼東東),與後端upstream創建鏈接有什麼關係?
這兩個問題解決了,nginx做爲反向代理的最大客戶鏈接數的計算也就很明確了。
2014.06.01 0:30分更新:
nginx使用的epoll模型,
做爲web server時,在處理http請求時,若是做爲web服務器,一個worker進程就能夠用來響應一個用戶請求。
做爲反向代理時,用戶發送請求到nginx,nginx發送請求到後端被代理服務器,後端服務器相應給nginx,nginx將內容返回給用戶。
因爲epoll模型是不等待的,每一步都有多是由新建鏈接處理的,可是這也不能說明nginx做爲反向代理最大客戶鏈接數是須要除以4的。
2014.06.01 01:10更新:
http://wiki.nginx.org/EventsModule#worker_connections
2011年你們對此問題的討論:
http://mailman.nginx.org/pipermail/nginx/2011-February/024979.html
Antoine BONAVITA antoine_bonavita at yahoo.com
Thu Feb 3 11:43:22 MSK 2011
Previous message: Calculating the max. clients by worker_connections
Next message: Calculating the max. clients by worker_connections
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I would say "and nginx uses the fds (file descriptors) from the same pool to
connect to the upstream backen" (wiki quote). But that should be 2, not 4: I
agree with you on this.
If any of the gurus out there could shed light on this, I'm sure a lot of us
would appreciate.
Antoine.
Ryan Chan ryanchan404 at gmail.com
Thu Feb 3 19:38:49 MSK 2011
Previous message: Calculating the max. clients by worker_connections
Next message: Calculating the max. clients by worker_connections
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
In fact,
As normal web server, the maths would also be
max_clients = worker_processes * worker_connections / 2
since every browser opens 2 connections by default,
since browser uses 2 connections in HTTP 1.1.
好吧,如上討論內容,總有一個計算方式是有問題的,或者說你們對max_clients的理解不太同樣。
若是說max_clients指的是最大客戶端鏈接數,那nginx做爲通常web server的計算公式是正確的。若是max_clients指的是創建鏈接最大客戶數,因爲每個瀏覽器看了兩個併發鏈接,那麼nginx做爲反向代理的計算公式就是正確的。
我的認爲,max_clients 指nginx能夠處理的客戶端數(默認一個客戶端發送一個請求,若是客戶端併發兩個請求,那就只能再除以2了)。
最終的結論:
從用戶的角度,http 1.1協議下,因爲瀏覽器默認使用兩個併發鏈接,所以計算方法:
nginx做爲http服務器的時候:
max_clients = worker_processes * worker_connections/2
nginx做爲反向代理服務器的時候:
max_clients = worker_processes * worker_connections/4
或者從通常創建鏈接的角度:客戶併發鏈接爲1.
nginx做爲http服務器的時候:
max_clients = worker_processes * worker_connections
nginx做爲反向代理服務器的時候:
max_clients = worker_processes * worker_connections/2
nginx作反向代理時,和客戶端之間保持一個鏈接,和後端服務器保持一個鏈接。
clients與用戶數:
同一時間的clients(客戶端數)和用戶數仍是有區別的,當一個用戶請求發送一個鏈接時這兩個是相等的,可是當一個用戶默認發送多個鏈接請求的時候,clients數就是用戶數*默認發送的鏈接併發數了。
Calculating the max client in Nginx
Answer:
If you use Nginx as a web server, the max. number of client can be served at the same time by Nginx should be calculated by the following formula:
max_clients = worker_processes * worker_connections
But this does not equal to the number of users can be served at the same time by Nginx, since a lot of browsers open 2 connections to the web server at the same time.
有關高流量負載狀況下,nginx併發問題優化的一個文章:
http://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/
感謝:
互聯網運維圈子羣中的「Elean follow me」小夥伴.
互聯網上各類抄襲和被抄襲的文章,雖然大家一再地誤導我,各類坑我,可是我仍是最終跳過各類坑,一步一步把問題搞明白了。