一文走进 Nginx
Nginx 作为开源的轻量级的 HTTP 服务器,广泛应用于分布式应用架构中。本文简要介绍了 Nginx 的特点及使用场景、Nginx 的进程模型和请求处理流程,并结合不同场景进行配置,对 Nginx 的架构和实现原理有个初步的了解。
1.什么是Nginx
Nginx(engine X)是一个开源的轻量级的 HTTP 服务器,能够提供高性能的 HTTP 和反向代理服务。与传统的 Apache 服务器相比,在性能上 Nginx 占用系统资源更小、支持高并发,访问效率更高;在功能上,Nginx 不仅作为 Web 服务软件,还适用于反向代理、负载均衡等场景;在安装配置上,Nginx 更为简单、灵活。Nginx 因为并发性能和资源占用上的优势,已经广泛用于大中型互联网企业。
1.1 Nginx特点
- 支持高并发:Nginx 是专门为性能优化而开发的,采用内核 Poll 模型,单机能够支持几万以上的并发连接。
- 低资源消耗:Nginx 采取了分阶段资源分配技术,使得 CPU 与内存的占用率非常低。一般 1 万个非活跃的 HTTP Keep-Alive 连接在 Nginx 中仅消耗几 MB 内存。
- 高拓展性:设计极具扩展性,由多个不同功能、不同层次、不同类型且耦合度极低的模块组成。
- 高可用性:Nginx 支持热部署,其中的 master 管理进程与 worker 工作进程的分离设计;启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到 7×24 小时不间断地运行。
- 丰富的使用场景:可以作为 Web 服务端、HTTP 反向代理、负载均衡和前端缓存服务等场景使用。
- 开源协议:使用 BSD 许可协议,免费使用,且可修改源码。
1.2 Nginx使用场景
1.2.1 反向代理
代理服务器一般指代 局域网内部的机器通过代理服务发送请求到互联网上的服务器,代理服务器一般作用于客户端。代理服务器是介于客户端和 Web 服务器之间的服务器,客户端首先与代理服务器创建连接,然后根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或则获得目标服务器的指定资源。
正向代理:为了从原始服务器取的内容,客户端向代理发送一个请求并指定目标(Web 服务器),然后代理向 Web 服务器转交请求并将获得的内容返回给客户端,客户端必须要进行一些特别的设置才能使用正向代理。
- 像 VPN 就是正向代理,一般在浏览器中配置代理服务器的相关信息。
- 正向代理中代理的对象是客户端,代理服务器和客户端属于同一个 LAN,对服务器端来说是透明的。
反向代理:客户端发送请求到代理服务器,由代理服务器转发给相应的 Web 服务器进行处理,最终返回结果给客户端。
- 像 Nginx 就是反向代理服务器软件,对客户端暴露的其实是一个 VIP,不是真实的 Web 服务器的 IP。
- 反向代理的是对象是 Web 服务器端,代理服务器和 Web 服务端属于同一个LAN,对客户端来说是透明的。
使用反向代理的好处是客户端不需要任何配置就可以访问,对外暴露的是代理服务器的地址隐藏了真实服务器的地址,客户端只需要把请求发送给代理服务器,由代理服务器去选择后端的 Web 服务器,获取到数据后再返回给客户端。
1.2.2 负载均衡
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如 Web 服务器、FTP 服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简而言之,单个 Web 应用服务器不能承受日益增长的并发量请求,因此需要不断扩展 web 服务器来支撑高并发请求,根据不同的负载均衡策略将请求分配到各个服务器上。Nginx 支持三种不同的负载均衡策略:
- 轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉能够被自动剔除。轮询算法适合服务器配置相当,无状态且短平快的服务使用。
- weight 权重:指定轮询的几率,weight 和后端的访问比例成比例,weight 权重越高比例越大。通常用于后端服务器配置不均的情况。
- ip_hash:上面两种算法存在一个问题是就是无法做到会话保持,当用户登录到服务器上后,第二次请求的时候会被定位到服务器集群中的某一个,那么已经登录到某个服务器上的用户会重新定位到另一台,之前的登录信息会丢失。ip_hash 算法可以解决这个问题,当用户再次访问请求时,会通过 hash 算法自动定位到已经登录的服务器上,这样每个客户端可以固定在某个 web 服务器上,解决客户端 session 的问题。
1.2.3 动静分离
动静分离技术是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,将静态文件放在一个单独的 web 服务器上,加快解析速度,降低原来单个服务器的压力。在 Nginx 的配置中,在 server{} 段中加入带正则匹配的 location 来指定匹配项针对 PHP 的动静分离:静态页面交给 Nginx 处理,动态页面交给 PHP-FPM 模块或 Apache 处理。
1.3 Nginx功能模块说明
Nginx 由内核和模块组成,其中内核在设计上非常简洁,完成的工作非常简单,仅仅通过查找配置文件将客户端请求映射到一个 location block,而在这个 location 中所配置的每个指令将会启动不同的模块去完成相应的工作。
1.3.1 Nginx模块分类
Nginx 的模块从结构上分为核心模块、基础模块和第三方模块,其中用户根据自己的需要开发的模块都属于第三方模块:
- 核心模块:HTTP 模块、EVENT 模块和 MAIL 模块。
- 基础模块:HTTP Access 模块、HTTP FastCGI 模块、HTTP Proxy 模块和 HTTP Rewrite 模块。
- 第三方模块:HTTP Upstream Request Hash 模块、Notice 模块和 HTTP Access Key 模块。
Nginx http 功能模块 | 模块说明 |
---|---|
ngx_http_core_module | 包括一些核心的 http 参数配置,对应 Nginx 的配置为 HTTP 区块部分 |
ngx_http_access_module | 访问控制模块,用来控制网站用户对 Nginx 的访问 |
ngx_http_gzip_module | 压缩模块,对 Nginx 返回的数据压缩,属于性能优化模块 |
ngx_http_fastcgi_module | FastCGI 模块,和动态应用相关的模块,例如 PHP |
ngx_http_proxy_module | proxy 代理模块 |
ngx_http_upstream_module | 负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查 |
ngx_http_rewrite_module | URL 地址重写模块 |
ngx_http_limit_conn_module | 限制用户并发连接数及请求数模块 |
ngx_http_limit_req_module | 根据定义的 key 限制 Nginx 请求过程的速率 |
ngx_http_log_module | 访问日志模块,以指定的格式记录 Nginx 客户访问日志等信息 |
ngx_http_auth_basic_module | Web 认证模块,设置 Web 用户通过账号、密码访问 Nginx |
ngx_http_ssl_module | ssl 模块,用于加密的 http 连接,如 https |
ngx_http_stub_status_module | 记录 Nginx 基本访问状态信息等的模块 |
1.3.2 Nginx模块功能
Nginx 模块常规的 HTTP 请求和响应的过程如上图所示,Nginx 模块从功能上分为以下三类:
- Handlers 处理器模块:此类模块直接处理请求,并进行输出内容和修改 headers 信息等操作。Handlers 处理器模块一般只能有一个。
- Filters 过滤器模块:此类模块主要对其他处理器模块输出的内容进行修改操作,最后由 Nginx 输出。
- Proxies 代理类模块:此类模块是 Nginx 的 HTTP Upstream 之类的模块,这些模块主要与后端一些服务比如 FastCGI 等进行交互,实现服务代理和负载均衡等功能。
Nginx 本身处理的工作很少,当它接到一个 HTTP 请求时,通过查找配置文件将此次请求映射到一个 location block,而此 location 中所配置的各个指令则会启动不同的模块去完成工作。
2.Nginx架构解析
2.1 Nginx进程模型
Nginx 默认采用多进程工作方式,在 Nginx 启动后,会运行一个 master 进程和多个 worker 进程。
- master 主要用来管理 worker 进程,充当整个进程组与用户的交互接口,同时对进程进行监护,实现 worker 进程的重启服务、平滑升级、更换日志文件、配置文件实时生效等功能;
- worker 进程用来处理基本的网络事件,worker 之间是平等的,他们共同竞争来处理来自客户端的请求。一个请求只能在一个 worker 进程中处理,一个 worker 进程不可能处理其它 worker 进程中的请求。
另外在 Nginx 架构中还有 Cache Loader 和 Cache Manager 进程,Cache Loader 进程加载缓存索引文件信息;Cache Manager 进程管理磁盘的缓存大小,超过预定值大小后最小使用的数据将被删除。
2.1.1 Master管理进程
Master 进程主要用来管理 worker 进程,具体包括如下 4 个主要功能:
- 接收来自外界的信号;
- 向各 worker 进程发送信号;
- 监控 woker 进程的运行状态;
- 当 woker 进程退出后(异常情况下),会自动重新启动新的 woker 进程。
Master 进程接受到命令重启 Nginx 进程(./nginx -s reload
),会按照以下流程:
- 首先 master 进程在收到重启命令后,会先重新加载配置文件,然后再启动新的 worker 进程,并向所有老的 worker 进程发送信号,告诉他们可以光荣退休了。
- 新的 worker 进程在启动后,就开始接收新的请求,而老的 worker 在收到来自 master 的信号后,就不再接收新的请求,并且处理完当前进程中的所有未处理完的请求后,再退出。
2.1.2 Worker工作进程
Worker 工作进程之间是对等的,每个进程处理请求的机会也是一样的。Nginx 采用 异步非阻塞 的方式来处理网络事件,具体流程如下:
- 接收请求:首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。
- 所有 worker 进程的 listenfd 会在新连接到来时变得可读,每个 work 进程都可以去 accept 这个 socket(listenfd)。
- 当一个 client 连接到来时,所有 accept 的 work 进程都会受到通知,但只有一个进程可以 accept 成功,其它的则会 accept 失败。
- 为保证只有一个进程处理该连接,Nginx 提供了一把共享锁
accept_mutex
来保证同一时刻只有一个 work 进程在 accept 连接。 - 所有 worker 进程在注册 listenfd 读事件前抢
accept_mutex
,抢到互斥锁的那个进程注册 listenfd 读事件,在读事件里调用 accept 接受该连接。
- 处理请求:当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接。
由上可以看出,一个请求完全由 worker 进程处理,并且只在一个 worker 进程中处理。
2.2 Nginx请求处理流程
Nginx 工作进程会监听套接字上的事件(accept_mutex 和 kernel socketsharding),来决定什么时候开始工作。事件是由新的连接初始化的,这些连接会被分配给状态机。
Nginx中有三大类状态机:处理应用层的 HTTP 状态机、处理 TCP/UDP 的 4 层的传输层状态机、处理邮件的 MAIL 状态机。其中,HTTP 状态机最为常见。
在多种流量进入 Nginx 后,Nginx 的三种状态机在 Nginx 解析出请求后,会动用线程池处理调用,将静态资源、反向代理、错误日志等信息分别导向不同的出口,比如 fastcgi 会导向 PHP 处理、html 会导向 nginx 处理,并将处理请求日志记录到本地或远程服务器中。
2.3 Nginx多进程IO模型
2.3.1 Nginx多进程模型
Nginx 默认使用多进程的工作方式,相比较多线程的方式,有以下好处:
- 首先,对于每个 worker 进程来说,独立的进程不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多;
- 其次,采用独立的进程,可以让进程之间相互不会影响,一个进程退出后,其它进程还在工作,服务也不会中断,master 进程则很快启动新的 worker 进程;
- 再次,为 Nginx 热部署提供了支持。在修改配置文件
nginx.conf
后,重新生成新的 worker 进程,新的 worker 进程会以新的配置处理请求,而老的 worker 进程,等把以前的请求处理完成以后,kill 掉就可以。
2.3.2 Nginx异步非阻塞事件模型
异步非阻塞事件是怎么回事?先看一个请求的完整过程,首先请求过来建立连接,然后再接收数据再发送数据,具体到系统层就是 IO 读写事件。当读写事件没有准备好,如果不采用非阻塞的方式,就得阻塞调用,阻塞调用会进入内核等待,导致 CPU 资源被其它进程占用。当并发请求越大时,等待的事件越多,CPU 利用不上去,并发也上不去。因此 Nginx 使用非阻塞的事件模型,系统中事件模型有很多中,比如 select / poll / kqueue / epoll 等,Nginx 采用 epoll 模型。
Epoll 模型基于事件驱动机制,可以监控多个事件是否准备完毕,如果可以,就放入 epoll 队列,这个过程是异步的,worker 进程只需要从 epoll 队列循环处理即可。Epoll 调用过程如下图所示:
3.Nginx部署与配置
3.1 Nginx环境部署
(1)下载安装包,官网链接:https://nginx.org/en/download.html。
(2)解压安装包
[root@tango-rac01 src]# tar -xzvf nginx-1.22.1.tar.gz
(3)编译配置
[root@tango-rac01 nginx-1.22.1]# ./configure
[root@tango-rac01 nginx-1.22.1]# make
[root@tango-rac01 nginx-1.22.1]# whereis nginx
nginx: /usr/local/nginx
(4)启动 Nginx
[root@tango-rac01 nginx-1.22.1]# cd /usr/local/nginx/
[root@tango-rac01 nginx]# ./sbin/nginx
[root@tango-rac01 nginx]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 *:80
(5)访问页面 ip:80
3.2 Nginx不同场景配置
3.2.1 Nginx配置文件介绍
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
- 全局块:配置影响 nginx 全局的指令。一般有运行 nginx 服务器的用户组,nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。
- events 块:配置影响 nginx 服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- http 块:可以嵌套多个 server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type 定义,日志自定义,是否使用 sendfile 传输文件,连接超时时间,单连接请求数等。
- server 块:配置虚拟主机的相关参数,一个 http 中可以有多个 server。
- location 块:配置请求的路由,以及各种页面的处理情况。
3.2.2 反向代理配置
简单配置如下:
server {
keepalive_requests 120;
listen 80;
server_name 192.168.112.135;
location ~ /news/ {
proxy_pass http://192.168.112.101:8080;
}
location ~ /prod/ {
proxy_pass http://192.168.112.101:8081;
}
}
访问 http://192.168.112.135:80/news/
时会跳转到 http://192.168.112.101:8080
。
访问 http://192.168.112.135:80/prod/
时会跳转到 http://192.168.112.101:8081
。
3.2.3 负载均衡配置
配置如下:
upstream myServer {
server 192.168.112.101:8080 down;
server 192.168.112.101:8090 weight=2;
server 192.168.112.101:6060;
server 192.168.112.101:7070 backup;
}
#指定负载均衡策略为ip_hash
upstream myServer {
ip_hash
server 192.168.112.101:8080;
server 192.168.112.101:6060;
}
down
:表示当前的 server 暂时不参与负载。Weight
:默认为 1,weight 越大,负载的权重就越大。max_fails
:允许请求失败的次数默认为 1,当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。fail_timeout
:max_fails 次失败后,暂停的时间。Backup
:其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。
3.2.4 动静分离配置
配置如下:
server {
listen 10000;
server_name localhost;
#拦截后台请求
location / {
proxy_pass http:// 192.168.112.101:8888;
proxy_set_header X-Real-IP $remote_addr;
}
#拦截静态资源
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
root /static/;
autoindex on;
}
}
上述配置中,访问静态资源在根目录的 /static/
下。
4、总结
Nginx 作为开源的轻量级的 HTTP 服务器,广泛应用于分布式应用架构中。本文简要介绍了 Nginx 的特点及使用场景、Nginx 的进程模型和请求处理流程,并结合不同场景进行配置,对 Nginx 的架构和实现原理有个初步的了解。
参考资料:
https://www.nginx.com/resources/library/infographic-inside-nginx/
https://blog.csdn.net/hguisu/article/details/8930668
https://blog.csdn.net/khuangliang/article/details/122345060
https://blog.csdn.net/qq_42511550/article/details/125054697