一、Nginx如何通過連接池處理網絡請求
1、連接池
1、預分配的connections_n 個鏈接
http://nginx.org/en/docs/ngx_core_module.html#worker_connections Syntax: worker_connections number; Default: worker_connections 512; Context: events
1、設置的越大,占用的內存越多
2、每一個connections到底是用了多大的內存呢?
64位操作系統中:大小232字節事件大小為96 一個連接就是328
2、僅當在一次read中,沒有收到請求頭,才會算成超時。
http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout Syntax: client_header_timeout time; Default: client_header_timeout 60s; Context: http, server
定義用於讀取客戶端請求體的超時時間。超時僅設置在兩個連續讀取操作之間的時間段內,而不是用於整個請求體的傳輸。如果客戶端在此時間內不發送任何內容,則請求終止(408)(請求超時)錯誤。
3、nginx返回給客戶端的字節數,包括響應頭和響應體
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables $bytes_sent number of bytes sent to a client (1.3.8, 1.2.5)
NGIXN日志中的使用
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status [$request_length:$bytes_sent] "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
訪問日志
192.168.0.109 - - [01/Mar/2020:17:57:58 +0800] "GET /plus.gif HTTP/1.1" 304 [435:179] "http://192.168.0.123:8080/" "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/82.0.4068.5 Safari/537.36" "-
重點看:[435:179]
2、核心數據結構
二、內存池對性能的影響
1、允許精確調整每個連接內存分配connection_pool_size size
http://nginx.org/en/docs/http/ngx_http_core_module.html#connection_pool_size Syntax: connection_pool_size size; Default: connection_pool_size 256|512; Context: http, server
還可以分配更大的 、可以減少分配的次數
2、request_pool_size size
http://nginx.org/en/docs/http/ngx_http_core_module.html#request_pool_size Syntax: request_pool_size size; Default: request_pool_size 4k; $ Context: http, server
為什么這么小?對於連接而言需要的上下文信息特別少
三、所有worker進程協同工作的關鍵:共享內存
1、Nginx進程間的通訊方式
2、自旋鎖
當鎖的條件沒有滿足:也就是這把鎖被1號work進程正在使用、那么2號進程去請求鎖只要1號進程沒有釋放、那么2號會一直不停的請求這把鎖
假入一把鎖鎖住了一扇門、如果work1號進程已經拿到這把鎖、那么work2號去敲門發現里面已經有人了、就會就地休息、等待1號進程出來以后通知她、而自旋鎖就不一樣work2進程發現門里有人會持續的敲門
3、共享內存:nginx那些模塊使用到了共享內存:單鏈表
1、為什么需要一個鏈表?
因為這個10M是有限的、但我們的lua代碼涉及到了應用代碼、我們的應用代碼很容易超過10M的限制
當超過了10M的限制、他用LRU淘汰、最早set或get不同的節點會被淘汰掉
2、單鏈表模塊
Ngx_http_upstream_zone_module Ngx_stream_upstream_zone_module
4、nginx那些模塊使用到了共享內存:紅黑樹
比如我們想做限速、流控不能容忍在內存中做的、否則一個work進程對於某一個用戶觸發了一個流控、而其他的work進程確不知道、所以我們只能在共享內存中做的
Ngx_stream_limit_conn_module Ngx_http_limit_conn_module Ngx_stream_limit_req_module Ngx_http_file_cache Ngx_http_proxy_module http cache Ngx_http_scgi_module Ngx_http_uwsgi_module Ngx_http_fastcgi_module Ngx_http_ssl_modul ssl Ngx_mail_ssl_module Ngx_stream_ssl_module
這些模塊都有一個共同的特點:我需要快速的插入和刪除
比如我現在發現了一個客戶端、需要對他限速、如果限速達到了、我要把這個客戶端從我的限速容器中移出、都需要非常的快速
3、Ngx_http_lua_api :OpenResty共享內存代碼示例
定義了一個sdk sdk的名稱叫做lua_shared_dict
當這個指令出現的時候它會分配一塊共享內存大小為:10M 這塊共享名稱叫做dogs
使用紅黑樹來保存每一個key value
四、 用好共享內存的工具:Slab管理器
最多兩倍內存消耗
2、應用場景:適合小對象
因為我們要分配的內存特別小、比如分配小於一個頁面的大小、因為它很少會有碎片 有時候我分配的內存數據機構是固定大小的甚至需要初始化、那么原來的數據結構都還在、這樣就避免了重復初始化
2、ngx_slab_stat模塊安裝
1、下載
wget http://tengine.taobao.org/download/tengine-2.3.2.tar.gz tar xf tengine-2.3.2.tar.gz [root@ceph-client ngx_slab_stat]# pwd /usr/local/src/tengine-2.3.2/modules/ngx_slab_stat [root@ceph-client ngx_slab_stat]# ll total 44 -rw-rw-r--. 1 root root 204 Sep 5 2019 config -rw-rw-r--. 1 root root 6627 Sep 5 2019 ngx_http_slab_stat_module.c -rw-rw-r--. 1 root root 3465 Sep 5 2019 README.cn -rw-rw-r--. 1 root root 3501 Sep 5 2019 README.md -rw-rw-r--. 1 root root 21430 Sep 5 2019 slab_stat.patch drwxrwxr-x. 2 root root 20 Sep 5 2019 t
2、編譯安裝
[root@ceph-client openresty-1.13.6.2]# pwd /usr/local/src/openresty-1.13.6.2 [root@ceph-client openresty-1.13.6.2]#./configure --add-module=../tengine-2.3.2/modules/ngx_slab_stat/ [root@ceph-client openresty-1.13.6.2]#make [root@ceph-client openresty-1.13.6.2]#make install
3、替換nginx二進制文件 ,當前nginx文件最好備份下,避免出問題
[root@ceph-client conf]# nginx -s reload [root@ceph-client conf]# netstat -lntup|grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 22522/nginx: master [root@ceph-client]#cp /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx [root@ceph-client bin]# ll /usr/local/bin/ total 15464 lrwxrwxrwx. 1 root root 37 Mar 4 09:57 nginx -> /usr/local/openresty/nginx/sbin/nginx -rwxr-xr-x. 1 root root 15832600 Aug 19 11:11 nginx_no_slab_stat /usr/local/openresty/nginx/sbin/nginx
4、驗證是否安裝成功
[root@ceph-client ~]# nginx -V nginx version: openresty/1.13.6.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt=-O2 --add-module=../ngx_devel_kit-0.3.0 ..... --add-module=/usr/local/src/openresty-1.13.6.2/../tengine-2.3.2/modules/ngx_slab_stat --with-stream --with-stream_ssl_module --with-http_ssl_module
3、統計Slab使用狀態
nginx配置文件
[root@ceph-client ~]# grep -vE "#|^$" /usr/local/openresty/nginx/conf/nginx.conf worker_processes 2; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; lua_shared_dict dogs 10m; server { listen 80; server_name localhost; location = /slab_stat { slab_stat; } location = /set { content_by_lua_block{ local dogs = ngx.shared.dogs dogs:set("JIM",8) ngx.say("STORED") } } location = /get { content_by_lua_block{ local dogs = ngx.shared.dogs ngx.say(dogs:get("JIM")) } } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
[root@ceph-client ~]# curl localhost:80/set STORED [root@ceph-client ~]# curl localhost:80/get 8 [root@ceph-client conf]# curl http://localhost:80/slab_stat * shared memory: dogs total: 10240(KB) free: 10168(KB) size: 4(KB) pages: 10168(KB) start:00007F2DE5FFC000 end:00007F2DE69EC000 slot: 8(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 16(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 32(Bytes) total: 127 used: 1 reqs: 1 fails: 0 slot: 64(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 128(Bytes) total: 32 used: 1 reqs: 1 fails: 0 slot: 256(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 512(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 1024(Bytes) total: 0 used: 0 reqs: 0 fails: 0 slot: 2048(Bytes) total: 0 used: 0 reqs: 0 fails:
五、 哈希表的max_size與bucket_size如何配置
1、Nginx容器
2、Nginx哈希表
1、nginx的哈希表和我們正常見得到hash表有什么不同?
從實現層面看:是相似的、哪里不同?應用場景不同:
僅僅應用於靜態不變的內容、也就是在運行過程中這個hash表通常不會存在插入和刪除的操作也就是說剛啟動的時候已經確定hash表中一共有多少元素
3、哈希表配置
1、Max size的作用
Max size是最大的Bucket size、而不是實際上使用的的多少、Max size的作用限制了最大化的使用我們的內存
2、我們的哈希表為什么要向64節對齊了?
如果一個Bucket是59字節、如果是緊密排列在一起的、這樣你取第一個字節取了兩個元素、然后第二個元素就要取兩次、為了這種取兩次的的問題nginx在它的代碼中自動的向上對齊了
3、配置Bucket size需要注意兩個問題
所以我們在配置Bucket size需要注意兩個問題
如果沒有特殊需求建議配置不要超過64字節、避免一個元素取兩次 如果你配置70字節、它就會給我們分配128字節
4、所有使用hash表的結構的模塊都有哪些特點了?
他們對所有的變量使用了hash表