1、網絡收發與Nginx事件間的對應關係
一、網絡傳輸
二、TCP流與報文
三、TCP協議與非阻塞接口
2、Nginx網絡事件實例演示
一、TCP層:本地打開了53842,Nginx打開的是8080端口 進程與進程通訊這件事情
二、IP層:本機IP地址:192.168.0.109 nginx服務器的IP地址:192.168.0.123(機器和機器以前怎麼互相找到的問題)
三、三次握手
- windows先向nginx發送一個SYN
- 相反的nginx所在的linux也會向windos發送一個SYN,這個時候nginx是沒有感知到的、由於這是一個半打開的狀態
- 直到widows再向nginx所在的linux服務器發送一個ACK時,linux操做系統纔會通知nginx這時有一個讀事件須要處理
3、 Nginx的事件驅動模型
一、Nginx的事件驅動模型
知道Nginx事件循環有什麼好處?
- 第三方模塊作大量的CPU計算,致使我處理一個事件會特別長,會致使後續隊列中的大量事件長事件得不處處理
- 因此nginx沒法容忍第三方模塊長時間使用CPU執行計算任務
- 咱們看到gzip模塊不是一次計算而是分段計算
4、epoll的優劣和原理
一、epoll的優劣
二、epoll的原理
三、場景描述:
有100萬用戶同時與一個進程保持着TCP鏈接,而每一時刻只有幾十個或幾百個TCP鏈接是活躍的(接收到TCP包),
也就是說,在每一時刻,進程只須要處理這100萬鏈接中的一小部分鏈接。那麼,如何才能高效地處理這種場景呢?
進程是否在每次詢問操做系統收集有事件發生的TCP鏈接時,把這100萬個鏈接告訴操做系統,而後由操做系統找出其中有事件發生的幾百個鏈接呢?html
四、select和poll如何處理:
每次收集事件時,都把這100萬鏈接的套接字傳給操做系統(這首先就是用戶態內存到內核態內存的大量複製),而由操做系統內核尋找這些鏈接上有沒有未處理的事件,將會是巨大的資源浪費linux
這裏有個很是明顯的問題,即在某一時刻,進程收集有事件的鏈接時,其實這100萬鏈接中的大部分都是沒有事件發生的。nginx
五、epoll如何處理
它在Linux內核中申請了一個簡易的文件系統,把原先的一個select或者poll調用分紅了3個部分:windows
- 調用epoll_create創建1個epoll對象(在epoll文件系統中給這個句柄分配資源)
- 調用epoll_ctl向epoll對象中添加這100萬個鏈接的套接字
- 調用epoll_wait收集發生事件的鏈接。
這樣,只須要在進程啓動時創建1個epoll對象,並在須要的時候向它添加或刪除鏈接就能夠了數組
所以,在實際收集事件時,epoll_wait的效率就會很是高,由於調用epoll_wait時並無向它傳遞這100萬個鏈接,內核也不須要去遍歷所有的鏈接。bash
六、這是如何實現的
維護了一個epitem的數據結構,他經過兩種數據結構把這兩件事件分開實現服務器
也就是Nginx每次取活躍鏈接的時候,咱們只須要去遍歷一個鏈表,這個鏈表裏僅僅只有活躍的的鏈接、這樣咱們速度效率就會很高網絡
一、建立:Nginx收到80端口創建鏈接的請求,請求鏈接成功之後,這時候我要添加一個讀事件,這個讀事件是用來讀取http消息的,這個時候我可能會添加一個新的事件、或者是寫事件數據結構
這個添加我只會放到紅黑樹中,二叉平衡樹能保證個人插入效率是logn的複雜度併發
二、添加:當操做系統接收到網卡中發送來一個報文的時候,這個鏈表就會增長一個連接
三、修改:讀取一個事件的時候鏈表天然就沒了
四、刪除:若是我我不想再處理讀事件和寫事件,我只要從這個平衡二叉樹移除一個節點
五、獲取句柄:就是遍歷活躍連接的鏈表,從內核態讀取到用戶態
5、Nginx的請求切換、同步&異步、阻塞&非阻塞之間的區別
一、Nginx的請求切換
每作一次切換大概須要5微妙,雖然很小,當併發量很大時切換須要的時間是指數級的增長
而Nginx直接在用戶態進行切換、操做系統給了nginx足夠處理請求的時間
二、阻塞調用
三、非阻塞調用
四、非阻塞調用下的同步與異步
反向代理的有一個特色:去考慮上游的服務處理請求是不足的,因此若是是一個有body的http請求,先把body接收完、再向上游發起鏈接
6、 Nginx的模塊到底是什麼?
一、前提
一、提供了那些配置項:gzip模塊官網查詢
http://nginx.org/en/docs/http/ngx_http_gzip_module.html
二、我如何肯定某個模塊編譯到nginx中呢?
有一個數組叫ngx_module_t *ngx_modules[]這個數組包含了編譯進了nginx的模塊,咱們找一gzip摸快
[root@nginx objs]# pwd /usr/local/src/nginx-1.14.2/objs [root@nginx objs]# cat ngx_modules.c #include <ngx_config.h> #include <ngx_core.h> extern ngx_module_t ngx_core_module; ...... extern ngx_module_t ngx_http_not_modified_filter_module; ngx_module_t *ngx_modules[] = { &ngx_core_module, ...... &ngx_http_gzip_filter_module, ...... &ngx_http_not_modified_filter_module, NULL }; char *ngx_module_names[] = { "ngx_core_module", ...... "ngx_http_not_modified_filter_module", NULL };
三、如何肯定支持那些指令?
ngx_command_t 這個結構體是一個數組、數組中的每個成員是他所支持的指令名
[root@luoahong modules]# pwd /usr/local/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/http/modules [root@luoahong modules]# cat -n ngx_http_gzip_filter_module.c ...... static ngx_command_t ngx_http_gzip_filter_commands[] = { { ngx_string("gzip"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |NGX_CONF_FLAG, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, enable), NULL }, { ngx_string("gzip_buffers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, ngx_conf_set_bufs_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, bufs), NULL }, { ngx_string("gzip_types"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_types_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, types_keys), &ngx_http_html_default_types[0] }, { ngx_string("gzip_comp_level"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, level), &ngx_http_gzip_comp_level_bounds }, { ngx_string("gzip_window"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, wbits), &ngx_http_gzip_window_p }, { ngx_string("gzip_hash"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, memlevel), &ngx_http_gzip_hash_p }, { ngx_string("postpone_gzipping"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, postpone_gzipping), NULL }, { ngx_string("gzip_no_buffer"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, no_buffer), NULL }, { ngx_string("gzip_min_length"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, min_length), NULL }, ngx_null_command }; ......