connection是什么?
connection是對tcp連接的封裝,包括連接的socket和讀事件、寫事件。利用connection,我們可以很方便的建立連接、發送數據和接受數據,我們可以與任何后端服務打交道。其中,Nginx的http請求處理也是建立在connection上的。
Nginx如何通過connection處理一個連接?
- Nginx在啟動時,會解析配置文件,得到需要監聽的端口和IP地址。
- 在master進程里初始化好這個監控的socket(即創建socket,設置addrreuse等,綁定到指定的ip地址端口,然后監聽)
- fork多個子進程出來,子進程們會競爭accept的新的連接。
- 客戶端向Nginx發起連接
- 客戶端與服務端通過三次握手后建立了一個連接
- 某一個子進程accept成功該連接,得到了該連接的socket(socket是一個接口,在用戶進程與TCP/IP協議之間充當中間人,完成TCP/IP協議的書寫,用戶只需理解接口即可)
- 該子進程創建Nginx對連接的封裝,即ngx_connection_t結構體
- 設置讀寫時間處理函數,添加讀寫事件來與客戶端進行數據交互
- Nginx或客戶端主動關掉連接
Nginx作為客戶端請求其他服務時如何處理連接?
- Nginx先獲取一個ngx_connection_t結構體
- 創建socket並設置socket的屬性(如非阻塞)
- 添加讀寫事件
- 調用connect/read/write來調用連接
- 關掉連接
- 釋放ngx_connection_t
Nginx能建立的最大連接數是多少?
Nginx通過設置worker_connectons來設置每個進程支持的最大連接數,如果該值大於nofile,那么實際的最大連接數就是nofile(操作系統中一個進程能夠打開的fd(fd為文件描述符fd,作為進程文件打開表項的指針)的最大數,可通過ulimit -n命令得到。一個socket占用一個fd,當fd用完的時候,再創建socket就會失敗)。
每個worker進程都有一個獨立的連接池(worker_connections大小的一個ngx_connection_t結構的數組),Nginx通過一個鏈表free_connections來保存所有空閑的ngx_connection_t,每次獲取一個連接時,就從free_connections獲取一個,用完后再放回空閑鏈表里。
總的來說,對於http請求本地資源來說,能夠支持的最大並發數量是worker_connections*worker_processes,而如果是http作為反向代理來說,最大並發數量為worker_connections*worker_processes/2,因為反向代理服務器,每個並發會建立與客戶端的連接和與后端服務的鏈接,會占用兩個鏈接。
以上總結參考https://mp.weixin.qq.com/s/bXtI45d7M-XjkJH3ARZiMQ