• Nginx架构基础


    1.Nginx请求处理流程

    传输层/HTTP/Mail状态机分别对应着配置中的stream/http/mail块的配置。

    • 每个处理完的请求都会记录access日志和error日志。
    • 静态资源中,当内存不足以缓存住所有的文件的时候,像sendfile/AIO这些会退化为阻塞调用,所以这边需要一个线程池来处理

    2.Nginx进程结构

            nginx为什么要采用多进程结构而不是多线程结构呢?

    nginx为了实现高可用性和高可靠性,如果使用多线程结构,多线程结构是共享同一块内存,当某一个第三方模块导致地址越界的时候,会导致整个nginx进程全部挂掉。

    master模块中,第三方通常不会加入自己的代码,master进程设计的目的是来做worker进程的管理,请求的处理是worker来做的,master进程主要做的是,监控worker进程,是否需要重新载入文件等...

            worker进程间的通信都是通过共享内存来解决的。

            优化点:worker进程和CPU个数保持一致;worker进程和固定CPU进行绑定,这样就可以更高的利用每个CPU上的缓存,减少缓存失效问题。

    3.reload重新加载配置文件

    1. 向master进程发送HUP信号
    2. master进程校验配置语法是否正确
    3. master进程打开新的监听端口
    4. master进程用新配置启动新的worker子进程
    5. master进程向老worker子进程发送QUIT信号
    6. 老worker进程关闭监听句柄,处理完当前连接后结束

     4.热升级流程

    1. 将旧的nginx文件替换为新的nginx文件
    2. 向master进程发送USR2信号
    3. master进程修改pid文件名,加后缀.oldbin
    4. master进程用新的nginx文件启动master进程
    5. 向老的master进程发送quit信号,关闭老master进程
    6. 回滚:向老master发送HUP,向新master发送QUIT

    问题点:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。所以老master推出后,新的master并不会退出

     5.优雅的关闭worker进程

    1. 设置定时器worker_shutdown_timeout
    2. 关闭监听句柄(epl_del)
    3. 关闭空闲连接
    4. 在循环中等待全部连接关闭(此阶段可能会比较耗时)
    5. 退出进程

    6.Nginx事件循环

    1. nginx首先根据本地配置的监听端口,启动服务器,等待新的事件进来,相对于epoll_wait
    2. 当操作系统接受到一个三次握手建立连接的报文的时候,并且处理完握手流程后,就会通知epoll_wait阻塞方法,告诉他可以往下走了,同时可以唤醒nginx的worker进程
    3. 操作系统会将准备好的事件放在事件队列中,从事件队列中可以获取到要处理的事件,比如TCP连接,tcp的请求报文...
    4. 接着会处理事件,但是在处理事件的过程中,可能会产生新的事件(比如添加定时器事件,如果连接建立成功后,1分钟没有请求,关闭连接)

    7.epoll的优劣及原理

            每次处理100w个连接的时候,可能活跃的只有几百个,而select和poll每次去操作系统取活跃事件的时候,都需要100w个链接都扔给操作系统,由操作系统判断,哪些有事件进来了。

            epoll通过红黑树和链表实现,链表里面仅仅只有活跃的连接,而针对读写事件,都是添加到红黑树中,二叉平衡树保证效率只有logn,如果不想处理读或者写事件,那么只需要去平衡二叉数中,移除对应节点即可。

            链表节点的增减:当读取一个事件的时候,链表中即少一个节点,当操作系统收到网卡中发送过来的一个报文的时候,就会添加一个节点。

            链表存放的是活跃事件;网卡收到报文形成事件,放入该链表;二叉树是全集事件,包括不活跃事件,相当于链表的字典,用于快速查询。

     8.Nginx模块

            nginx可以添加一个新的模块,其中主要涉及nginx_module_t。

    index:定义每个模块的顺序,index靠前的,如果和后面的模块冲突,他们会阻止后面的模块生效。

    ngx_commond_t:定义了所有的配置

    启停方法:最下面的7个方法(任何一个第三方模块,都有可能在master,worker执行)

    type:定义模块属于哪个类型的模块,如图2所示(

    NGX_CORE_MODULE衍生出NGX_HTTP_MODULE,NGX_EVENT_MODULE,NGX_STREAM_MODULE)

    9.Nginx如何通过连接池处理网络请求

            connections代表的是连接池,read_events和write_event分别对应的可读和可写事件,和连接是通过序号对应起来的。 

            每个连接对应232字节大小,在nginx中每个事件对应一个ngx_events_s结构体,其大小为96个字节。所以一个连接会对应232+96 * 2个字节大小。

            ngx_events_s中handler是一个回调方法(很多第三方模块把它设置为自己的方法),timer是超时

            ngx_connection_s中的sent,代表这个连接上发送了多少字节数据。 pool为内存池。

     

  • 相关阅读:
    IDEA 新版本设置菜单展开
    Python机器视觉--OpenCV入门--OpenCV鼠标绘制图形
    生态系统服务—土壤侵蚀强度空间分布/降雨侵蚀力
    PHP上网网址电影视频导航网站设计
    [附源码]Python计算机毕业设计Django企业售后服务管理系统
    springboot集成swagger3.0
    Spring 框架学习(八)——AOP 的认识与使用
    火爆全网的头戴式耳机,Y2K辣妹时髦单品——Umelody轻律 U1头戴式耳机!
    electron打包后主进程下载文件崩溃
    【时间序列分析】A Transformer-based Framework for Multivariate Time Series Representation Learning论文笔记
  • 原文地址:https://blog.csdn.net/c243311364/article/details/125230822