Nginx核心知識100講學習筆記(陶輝)Nginx架構基礎(三)


一、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管理器

1、Slab內存管理

1、這樣的數據結構會有內存的浪費、那么最多會浪費多少了?

最多兩倍內存消耗

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;
        }
    }
}

5、查看服務狀態

[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表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM