Nginx作为开源的轻量级的HTTP服务器,广泛应用于分布式应用架构中。本文简要介绍了Nginx的特点及使用场景、Nginx的进程模型和请求处理流程,并结合不同场景进行配置,对Nginx的架构和实现原理有个初步的了解。
Nginx(engine X)是一个开源的轻量级的HTTP服务器,能够提供高性能的HTTP和反向代理服务。与传统的Apache服务器相比,在性能上Nginx占用系统资源更小、支持高并发,访问效率更高;在功能上,Nginx不仅作为Web服务软件,还适用于反向代理、负载均衡等场景;在安装配置上,Nginx更为简单、灵活。Nginx因为并发性能和资源占用上的优势,已经广泛用于大中型互联网企业。
Nginx具有以下特点:
代理服务器一般指代局域网内部的机器通过代理服务发送请求到互联网上的服务器,代理服务器一般作用于客户端。代理服务器是介于客户端和Web服务器之间的服务器,客户端首先与代理服务器创建连接,然后根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或则获得目标服务器的指定资源。
使用反向代理的好处是客户端不需要任何配置就可以访问,对外暴露的是代理服务器的地址隐藏了真实服务器的地址,客户端只需要把请求发送给代理服务器,由代理服务器去选择后端的Web服务器,获取到数据后再返回给客户端。
负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
简而言之,单个Web应用服务器不能承受日益增长的并发量请求,因此需要不断扩展web服务器来支撑高并发请求,根据不同的负载均衡策略将请求分配到各个服务器上。Nginx支持三种不同的负载均衡策略:
动静分离技术是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,将静态文件放在一个单独的web服务器上,加快解析速度,降低原来单个服务器的压力。在Nginx的配置中,在server{}段中加入带正则匹配的location来指定匹配项针对PHP的动静分离:静态页面交给Nginx处理,动态页面交给PHP-FPM模块或Apache处理。
Nginx由内核和模块组成,其中内核在设计上非常简洁,完成的工作非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block,而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
Nginx的模块从结构上分为核心模块、基础模块和第三方模块,其中用户根据自己的需要开发的模块都属于第三方模块:
Nginx模块常规的HTTP请求和响应的过程如上图所示,Nginx模块从功能上分为以下三类:
Nginx本身处理的工作很少,当它接到一个HTTP请求时,通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作。
Nginx默认采用多进程工作方式,在Nginx启动后,会运行一个master进程和多个worker进程。
另外在Nginx架构中还有Cache Loader和Cache Manager进程,Cache Loader进程加载缓存索引文件信息;Cache Manager进程管理磁盘的缓存大小,超过预定值大小后最小使用的数据将被删除。
Master进程主要用来管理worker进程,具体包括如下4个主要功能:
Master进程接受到命令重启Nginx进程(./nginx -s reload),会按照以下流程:
Worker工作进程之间是对等的,每个进程处理请求的机会也是一样的。Nginx采用异步非阻塞的方式来处理网络事件,具体流程如下:
由上可以看出,一个请求完全由worker进程处理,并且只在一个worker进程中处理。
Nginx工作进程会监听套接字上的事件(accept_mutex和kernel socketsharding),来决定什么时候开始工作。事件是由新的连接初始化的,这些连接会被分配给状态机,Nginx中有三大类状态机:处理应用层的HTTP状态机、处理TCP/UDP的4层的传输层状态机和处理邮件的MAIL状态机,其中HTTP状态机最为常见。
在多种流量进入Nginx后,Nginx的三种状态机在Nginx解析出请求后,会动用线程池处理调用,将静态资源、反向代理、错误日志等信息分别导向不同的出口,比如fastcgi会导向PHP处理、html会导向nginx处理,并将处理请求日志记录到本地或远程服务器中。
Nginx默认使用多进程的工作方式,相比较多线程的方式,有以下好处:
异步非阻塞事件是怎么回事?先看一个请求的完整过程,首先请求过来建立连接,然后再接收数据再发送数据,具体到系统层就是IO读写事件。当读写事件没有准备好,如果不采用非阻塞的方式,就得阻塞调用,阻塞调用会进入内核等待,导致CPU资源被其它进程占用。当并发请求越大时,等待的事件越多,CPU利用不上去,并发也上不去。因此Nginx使用非阻塞的事件模型,系统中事件模型有很多中,比如select/poll/kqueue/epoll等,Nginx采用epoll模型。Epoll模型基于事件驱动机制,可以监控多个事件是否准备完毕,如果可以,就放入epoll队列,这个过程是异步的,worker进程只需要从epoll队列循环处理即可。Epoll调用过程如下图所示:
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
... #全局块events { #events块...
}http #http块
{... #http全局块server #server块{ ... #server全局块location [PATTERN] #location块{...}location [PATTERN] {...}}server{...}... #http全局块
}
1)简单配置如下:
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
1)配置如下:
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_hashserver 192.168.112.101:8080;
server 192.168.112.101:6060;
}
1)配置如下:
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/下。
Nginx作为开源的轻量级的HTTP服务器,广泛应用于分布式应用架构中。本文简要介绍了Nginx的特点及使用场景、Nginx的进程模型和请求处理流程,并结合不同场景进行配置,对Nginx的架构和实现原理有个初步的了解。
参考资料: