1, 简介

Nginx 是开源的轻量级 Web 服务器、反向代理服务器,以及负载均衡器和 HTTP 缓存器。其特点是高并发,高性能和低内存。
Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考验,最大能支持 50000 个并发连接数。 Nginx 还支持热部署,它的使用特别容易,几乎可以做到 7x24 小时不间断运行。 Nginx 的网站用户有:百度、淘宝、京东、腾讯、新浪、网易等。

2,模块架构

nginx 架构 - 图1

nginx 有一个master进程 和多个worker进程,worker数目一般与cpu数目相同。
master进程并不处理网络请求,主要负责调度工作进程,加载配置、启动工作进程及启停升级。
worker 进程负责处理网络请求与响应。

master进程职责

1, 读取并验证配置信息
2, 创建、绑定、关闭套接字
3, 启动、终止、维护worker进程的个数
4, master负责管理worker进程

问题: nginx已经启动,我们更改配置文件后reload,
1, 如果这个配置文件语法有误,nginx会怎么做?
配置文件有误,reload后,master会提示配置错误,并不会影响请求的处理。
2, 如果这个配置文件ok, nginx又会怎么做?
nginx支持热部署,主配置文件更新后,并不会立刻影响到worker进程,而是master等到worker进程的连接请求处理完后kill掉这个worker进程,然后重新生成一个worker进程,这样这个worker进程就会以新的配置启动。 重新加载配置文件不会中断正在处理的请求。

worker进程主要用来处理基本的网络事件:

1, 多个worker 进程之间是对等且相互独立的,他们争抢来自客户端的请求
2, 一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其他进程的请求
3, worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致。
4, 接受、传入并处理来自客户端的连接

每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。 这里的连接池里面的其实不是真实的连接,它只是一个worker_connections大小的一个nginx_connection_t结构的数据。并且,nginx会通过一个链表free_connections来保存所有的空闲nginx_connection_t,每次获取一个连接是,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。一个nginx能建立的最大连接数,应该是worker_connections worker_processes。 当然,这里说的最大连接数,对于http请求本地资源来说,能够支持的最大并发数量。对于反向代理,最大并发数量应该是worker_connections worker_processes/2。 因为作为反向代理,每个并发会建立与客户端的连接后后端服务的连接,会占用两个连接。

worker进程如何处理请求的?
nginx用一个独立的worker进程来处理一个请求,一个worker进程可以处理多个请求, 当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接。
一个请求,完全有worker进程来处理,而且只在一个worker进程中处理。采用这种方式的好处:
节省锁带来的开销,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题排查上,也会方便很多
独立进程不互相影响 采用独立的进程,可以让互相之间不会影响,一个进程退出后,其他进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程
在一次请求中无需进程切换**

nginx 架构 - 图2

nginx 惊群现象

惊群效应就是当一个fd的事件被触发时,所有等待这个fd的线程或进程都被唤醒。一般都是socket的accept() 会导致惊群,很多个进程都block在server socket的accept(),一但有客户端进来,所有进程的accept()都会返回,但是只有一个进程会读到数据数据,就是惊群。

nginx 采用accept-mutex来解决惊群问题,当一个请求到达的时候,只有竞争到锁的worker进程才会惊醒处理请求,其他进程会继续等待,结合timer_solution 配置的最大的超时时间继续尝试获取accept-mutex

nginx的IO通常使用epoll,epoll函数使用了I/O复用模型,与IO阻塞模型比较,I/O复用模型的优势在于可以同时等待多个套接字描述符就绪。

nginx的工作流程如下:

  1. master进程先建好需要listen的socket后,然后再fork出多个worker进程,这样每个worker进程都可以取accept这个socket
  2. 当一个client连接到来时,所有accept的worker进程都会收到通知,但只有一个进程可以accept,其他的则会accept失败,nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个worker进程accept连接,从而解决惊群问题
  3. 当一个worker进程accept这个连接后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完成的请求就结束了。

nginx00.jpeg

3,模块

nginx 的模块从结构上分为核心模块、基础模块、mail模块
核心模块: HTTP模块、Event模块、Mail模块
基础模块: http access模块、http proxy模块、http rewrite模块
第三方模块: http upstream request hash模块、notice模块、http access key 模块

nginx模块从功能上分为如下三类:
Handlers 处理器模块 此类模块直接处理请求,并进行输出内容和修改header信息等操作。handlers处理模块一般只有一个
Filters 过滤器模块 此类模块主要对其他处理器模块输出的内容进程修改操作,最后nginx输出
Proxies 代理类模块 此类模块是nginx的http Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等进程交换,实现服务代理和负载均衡功能。

nginx 架构 - 图4

4, 事件驱动模型

nginx 架构 - 图5

nginx的事件驱动模型,是由事件收集器、事件发送器、事件处理器组成,

事件收集器: 负责收集worker进程的各种IO请求
事件发送器: 负责将IO发送到事件处理器
事件处理器: 负责各种事件的响应工作

事件发送器 将每个请求放入一个 待处理事件列表,使用非阻塞IO方式调用 事件处理器 来处理该请求。

5, 信号

信号 对应进程全局标志位变量 含义
quit ngx_quit graceful shutdown
term或者 int ngx_terminate fast shutdown
USR1 ngx_reopen re-opening log files
USR2 ngx_change_binary upgrading an executable file
WINCH ngx_noaccept graceful shutdown of worker processes
HUP ngx_reconfigure 重读配置文件并使服务对新配置生效
CHLD ngx_reap 子进程意外结束,监控子进程