Nginx----高级
Nginx請求流程
?
?
?
?
Nginx進程結構
Nginx有兩種進程結構,一種是單進程(可以用于測試),一種是多進程(用于生產,默認)
Nginx會按需同時運行多個進程:一個主進程(master)和幾個工作進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。Nginx主要通過“共享內存”的機制實現進程間通信。worker 進程數,一般會設置成機器 cpu 核數。因為更多的worker 數,只會導致進程相互競爭 cpu,從而帶來不必要的上下文切換。
請求的緩存處理還是由work進程來執行的。CM:緩存的管理,CL:緩存的載入。
? ? ? ? ? ? ? ? ??
?
進程結構測試
1、ps -ef | grep nginx:可以查看到所有的work進程和cache進程2、../sbin/nginx -s reload:重新加載配置3、ps -ef | grep nginx:可以查看到之前所有的work進程和cache進程全部退出,重新生成新的work進程和cache進程4、kill -SIGHUP 9170:向master進程發送hub信號,結果和reload一樣5、ps -ef | grep nginx:可以查看到之前所有的work進程和cache進程全部退出,重新生成新的work進程和cache進程6、kill -SIGTERM 16982:向work進程發送退出信號7、ps -ef | grep nginx:16982進程退出,會重新生成一個work進程Nginx采用多進程而不是多線程,目的?
Nginx 的進程就是線程,即每個進程里只有一個線程,但這一個線程可以服務多個客戶端。
Nginx需要保證高可用和高可靠性,多線程線程之間共享某一快地址空間,如果某一個第三方某塊引發了一個地址空間導致的斷錯誤時,在地址越界出現時,會導致整個Nginx整個進程掛掉。
nginx采用多進程的方式,既可以避免因某個線程故障導致整個服務不可用的問題,也可以實現配置熱加載,不停服升級版本。
Nginx實現高并發原理?
參考:https://blog.csdn.net/m0_38110132/article/details/75126316
多進程之間通訊
多進程通訊可以使用共享內存,信號等,Nginx做進程管理通常只使用信號
Master進程可以監控wrok進程是否像master發送CHLD信號,因為子進程終止的時候回向父進程發送CHLD信號,如果work由于意外發生終止(認為輸入命令終止,但是我們一般不這么做,我們通過發送命令給master,讓master來終止work進程),此時master進程就會知道。
?
?
reload詳解
1、向master進程發送HUP信號(reload命令) 2、master進程校驗配置語法是否正確 3、master進程打開新的監聽端口(配置文件可能添加了新的端口) 4、master進程用新配置啟動新的worker子進程 5、master進程向老worker子進程發送QUIT信號 6、老worker進程關閉監聽句柄,處理完當前連接后結束進程?
?
熱升級流程詳解
1、將舊Nginx文件換成新Nginx文件(注意備份) 2、向master進程發送USR2信號 3、master進程修改pid文件名,加后綴.oldbin 4、master進程用新Nginx文件啟動新master進程 5、向老master進程發送QUIT信號,關閉老master進程 6、回滾:向老master發送HUP,向新master發送QUIT
?
?
如果優雅的關閉work進程(緩慢的關閉)
如果當前的work已經在處理請求,立刻關閉連接,就會造成用戶接受錯誤消息
1、設置定時器:worker shutdown timeout 2、關閉監聽句柄 3、關閉空閑連接 4、在循環中等待全部連接關閉 5、退出進程?
Nginx異步框架工作流程
?
?
?Nginx事件循環
?
?
epoll使用優勢
在大并發情況下,100萬個請求,往往活躍連接數就幾百個,所以epoll只需要處理這幾百個連接,而select和poll需要將這100萬個連接統統扔給操作系統,操作系統依次判斷哪些連接有事件進來,所以操作系統做了大量的無用功
?
非堵塞調用
?
?
Nginx如果通過連接池來處理網絡請求
?
?
欲分配的連接數目
參考:http://nginx.org/en/docs/ngx_core_module.html#worker_connections
Syntax: worker_connections number; Default: worker_connections 512; //512:512個數組,對應512個連接,生產中需要配置更大的 Context: events一個客戶端請求,需要使用一個connect連接(struct ngx_connection_s結構體占空間232個字節),一個連接對應兩個事件讀和寫(struct ngx_event_s結構體占空間96個字節),所以worker_connections分配越大,初始化就會占用232+96*2個字節
補充:讀和寫超時時間配置:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout
? 一個請求到來,work占用連接數是2個或者4個,如果請求訪問的是靜態資源,nginx可以直接給用戶返回,此時占用兩個,如果請求的是動態資源,nginx需要將請求轉發給tomcat,此時占用連接數是4個。
nginx有一個master,如果有4個work,每一個work支持的最大連接數是1024,支持的最大的并發數是多少?
(1) 4*1024/2
(2) 4*1024/4
nginx內存池
內存池是在真正使用內存之前,預先申請分配一定數量的、大小相等(一般情況下)的內存塊留作備用。當有新的內存需求時,就從內存池中分出一部分內存塊,若內存塊不夠用時,再繼續申請新的內存。
內存池的好處有減少向系統申請和釋放內存的時間開銷,解決內存頻繁分配產生的碎片,提示程序性能,減少程序員在編寫代碼中對內存的關注等
目前一些常見的內存池實現方案有STL中的內存分配區,boost中的object_pool,nginx中的ngx_pool_t,google的開源項目TCMalloc等。
? 在分配的內存上,nginx有小塊內存和大塊內存的概念,小塊內存 nginx在分配的時候會嘗試在當前的內存池節點中分配,而大塊內存會調用系統函數malloc向操作系統申請
在釋放內存的時候,nginx沒有專門提供針對釋放小塊內存的函數,小塊內存會在ngx_destory_pool 和 ngx_reset_pool的時候一并釋放
分配時怎么判斷是小塊內存還是大塊內存呢?
p->max=(size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)
Pagesize為內存一頁的大小,x86結構通常為4k
Max為內存池可分配大小和pagesize中較小的一個
如果需要分配的內存大于max,則認為是較大內存,否則為較小內存
Nginx分配內存的配置
連接內存池的大小:http://nginx.org/en/docs/http/ngx_http_core_module.html#connection_pool_size(默認512|516,需要保存大量的上下文,比如很長的url,header)
請求內存池的大小:http://nginx.org/en/docs/http/ngx_http_core_module.html#request_pool_size(默認4k,因為保存的上下文比較少,只需要幫組后面的請求讀取最初的一部分字節就可以了)
參考:https://www.cnblogs.com/magicsoar/p/6040238.html
?
Work進程之間協同工作
work之間如果需要共享數據,需要使用共享內存
信號量:會導致進程發生休眠狀態,比如當某一個塊內存被1號進程使用,那么2號就會進行休眠,等待1號通知2號鎖已經釋放
自旋鎖:比如當某一個塊內存被1號進程使用,那么2號就會不斷的試圖去解鎖,要求所有的Nginx模塊需要快速的使用共享內存
?
?
Slab內存管理
?
?
下載Tengine:http://tengine.taobao.org/download_cn.html?(slab沒有獨立的模塊,我們需要將tengin整個下載下來)
使用(編譯nginx)
make之后對nginx進行熱部署...
?
Nginx容器
數組
鏈表
隊列
哈希表
紅黑樹
基數樹
?
轉載于:https://www.cnblogs.com/yanxiaoge/p/11561448.html
總結
以上是生活随笔為你收集整理的Nginx----高级的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一年级下册计算机教学计划,【实用】一年级
- 下一篇: Nginx----实现https站点