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

1、網絡收發與Nginx事件間的對應關係

一、網絡傳輸

二、TCP流與報文

三、TCP協議與非阻塞接口

2、Nginx網絡事件實例演示

一、TCP層:本地打開了53842,Nginx打開的是8080端口 進程與進程通訊這件事情

二、IP層:本機IP地址:192.168.0.109 nginx服務器的IP地址:192.168.0.123(機器和機器以前怎麼互相找到的問題)

 三、三次握手

  1. windows先向nginx發送一個SYN
  2. 相反的nginx所在的linux也會向windos發送一個SYN,這個時候nginx是沒有感知到的、由於這是一個半打開的狀態
  3. 直到widows再向nginx所在的linux服務器發送一個ACK時,linux操做系統纔會通知nginx這時有一個讀事件須要處理

 

3、 Nginx的事件驅動模型

一、Nginx的事件驅動模型

知道Nginx事件循環有什麼好處?

  1. 第三方模塊作大量的CPU計算,致使我處理一個事件會特別長,會致使後續隊列中的大量事件長事件得不處處理
  2. 因此nginx沒法容忍第三方模塊長時間使用CPU執行計算任務
  3. 咱們看到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

  1. 調用epoll_create創建1個epoll對象(在epoll文件系統中給這個句柄分配資源)
  2. 調用epoll_ctl向epoll對象中添加這100萬個鏈接的套接字
  3. 調用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
};
......

二、什麼是?

 三、Nginx模塊的分類

相關文章
相關標籤/搜索