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模块的分类

相关文章
相关标签/搜索