大家好,我是Leo。

接下来我们聊聊Nginx,文章分类主要是​​MySQL​​ ,​​Redis​​,​​秒杀系统​​,​​RocketMQ​​,​​计算机网络​​,​​大厂面试​​,​​人生​​, ​​理财​​。先整理一下。方便粉丝更好的阅读,同时也方便自己不断的复习沉淀。

2000字先简单看看,我们过好新年,学习从未停止,技术永无止境,我们一起加油让学习成为习惯。如果阅读过程中有任何疑问,可以关注下面公众号联系我。

Nginx应用场景

  • 静态资源服务(通过本地文件系统提供服务)
  • 反向代理服务
  • Nginx的强大性能(高性能场景)
  • 缓存
  • 负载均衡
  • API服务
  • OpenResty

为什么会出现Nginx

  • 互联网数据量的快速增长
  • 全球化
  • 物联网
  • Apache比较低效,因为一个连接对应一个进程。

Nginx优点

  • 高并发,高性能
  • 可扩展性好(模块化设计非常好)
  • 高可靠性(持续不间断的运行数年)
  • 热部署(不停止服务的情况下,升级Nginx)
  • 轻量级,启动快

Nginx组成

  • Nginx二进制可执行文件(各模块源码编译出的一个文件)
  • Nginx.config 配置文件(控制Nginx的行为)
  • access.log 访问日志(记录每一条http请求信息)
  • error.log 错误日志(定位问题)

Nginx重载,热部署,日志切割,配置静态Web资源,搭建缓存的反向代理

Nginx请求处理流程

Nginx采用MasterWork架构。

  1. WEB以及TCP流量进入Nginx(Nginx内有传输层状态机,HTTP状态机,MAIL状态机)
  2. 传输层状态机解析出请求需要访问静态资源时,就可以访问静态资源,如果去做反向代理时,可以做磁盘缓存。
  3. nginx也作为负载均衡可以通过协议代理传输到后面的服务器
  4. 每一个处理完的请求都会记录到 Access访问日志和Error错误日志

什么是状态机?

因为Nginx使用的是非阻塞的事件驱动处理引擎。(也就是我们常说的epoll)

这种异步处理请求必须采用状态机

Nginx进程结构

Nginx的单进程结构不适合在生产环境中使用,适合在开发环境与测试环境中使用。

因为在生产环境中必须保证足够的健壮以及Nginx可以利用多核的特性。而单进程做不到这一点。所以默认配置都是打开多进程Nginx。

Nginx它有一个父进程叫 Mater Process 进程,在父进程旗下有子进程,子进程主要分两类

  • Worker 进程
  • Cache 进程

上面提到了很多子进程,这里聊一下为什么Nginx会使用子进程,而不是子线程来处理!

Nginx主要是为了考虑高可用性和高可靠性。如果多线程结构的话,线程之间是共享同一个地址空间的,当某一个第三方模块引发地址空间导致的段错误时,在地址越界时,会导致整个Nginx进程挂掉。

当采用多进程时,往往就不会出现全部宕机的问题。

Master Process 进程被引用进来,主要是管理旗下的Worker进程以及监控是否需要载入配置文件,是否需要做热部署。

所有的Worker进程是处理真正的请求的。

当缓存进入时,不止是给Worker线程使用的,也是给Cache Loader 和 Cache Manager 使用的。

Cache Loader 进程主要做缓存的导入,Cache Manager 进程主要做缓存的管理。同时也是为反向代理时,后端发来的动态请求做缓存所使用的。进程间的通信主要是用共享内存来解决的。

Nginx信号

信号的主要用途是解决父子进程之间的通信问题,能发送和处理信号的主要有以下三种

  • Master 进程
  • Worker 进程
  • Nginx 指令行

上文进程结构中我们说到了,Master Process进程主要是用来管理与监控Worker进程的,所以这个地方的Worker进程信号我们就不介绍了,我们主要介绍一下Master进程和 Nginx指令行。

Master 进程

监控Worker进程 CHLD

管理Worker进程的接收信息

  • TERM,INT
  • QUIT(优雅关闭)
  • HUP
  • USR1

Nginx指令行

  • reload:HUP
  • reopen:USR1
  • stop:TERM
  • quit:QUIT

收到 reload Nginx做了哪些

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

使用reload之后我们会发现,系统进程会越来越多,这里的主要原因是 在老worker进程和新worker进程并存的时候,会逐步关闭退出老worker,但是有些老worker与客户端正在保持请求处理,所以可能不会立即平滑的过度。

在Nginx最新版本中已经解决了这个问题,在新worker和老worker并存的时候,一一对应绑定了定时器,根据我们配置的参数可以平滑的过度。

Nginx热升级流程

  1. 旧的Nginx文件换成新的Nginx文件(注意备份)
  2. 向老master进程发送USR2信号
  3. master进程会修改pid文件名,加后缀.oldbin
  4. master进程用新的Nginx文件启动新的master进程
  5. 向老master进程发送QUIT信号,关闭老master进程

老master进程是一直存在的,这是方便我们进行回滚,当发现新的Nginx有问题,这个时候老的Nginx也存在,所以我们就可以通过向老master进程发送HUP信号,向新master发送QUIT信号完成回滚

优雅的关闭worker进程

这里就是reload命令流程底部的定时器细节

  1. 设置定时器 worker_shutdown_timeout
  2. 关闭监听句柄(保证所在的worker进程不会处理其他连接了)
  3. 关闭空闲连接(保证资源最大化,会去连接池关闭空闲没有使用的连接)
  4. 在循环中等待全部连接关闭(主要分两种,连接处理完,立即干掉。连接正在处理,这个就需要根据第一步的定时器参数去等待关闭)
  5. 退出进程(最终优雅的退出进程,因为没有影响到用户的使用)

如果不采用这种优雅的关闭worker进程,会导致用户收到错误