vieyahn2017 / iBlog

44 stars 0 forks source link

12.19 浅析Nginx的工作模式及原理 #380

Closed vieyahn2017 closed 3 months ago

vieyahn2017 commented 3 years ago

浅析Nginx的工作模式及原理

vieyahn2017 commented 3 years ago

浅析Nginx的工作模式及原理 2018-01-302018-01-30 14:42:56阅读 1.5K0 (微信公众号:IT技术精选文摘, 微信号:ITHK01, 欢迎订阅)

同Apache http server的Perfork工作模型类似,Nginx也有master,worker进程的概念。

第一,很显然,启动Nginx,就必须在端口启动监听服务,也就是套接字(ip+port),通常Nginx作为WEB SERVER和反向代理服务器都会在80端口监听。在LINUX上,要开启<1024端口的监听服务,必须用特权身份运行,也就是说master进程应该以root身份启动。

第二,那么master进程主要的职责是什么?

读取并验证配置信息。

创建,绑定,关闭套接字。

启动,终止,维护worker进程的个数。

master负责管理worker进程,这一点好理解,需要注意的是master在处理配置信息这一块。

假设nginx已经启动,我们更改配置文件后reload,如果这个配置文件语法有误,nginx会怎么做?

如果这个配置文件OK,nginx又会怎么做?

如果配置文件有误,reload后,master会提示配置错误,并不会影响请求的处理。

如果配置文件OK,reload后,什么时候生效呢?

Nginx支持热部署

如果主配置文件发生改变,那么并不会立刻影响到WORKER进程,而是MASTER等到WORKER进程的连接请求处理完毕后KILL掉这个WORKER进程,然后重新生成一个WORKER进程,这样这个WORKER进程就将以新的配置启动了。也就是说,老的连接用老的配置,新的连接用新的配置。重新加载配置文件不会中断正在处理的请求。

第三,worker进程是干嘛的?我们应该有多少个Worker进程?每一个Worker进程中有多少个线程?

在Nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环机制进行处理,而每个worker可以并行处理数千个的并发连接和请求。

Worker进程的个数,这个是可以配置的,但是一般而言,个数应该和CPU个数一致性,主要是为了CPU的进程切换。

那么Worker进程是做什么的?

接受,传入并处理来自客户端的连接;

提供反向代理等功能;

第四,worker进程如何处理请求的?

当一个请求来了,那么多个worker进程,谁去处理,还是几个一起处理?如何处理?

首先,要清楚的是,一个请求可以由一个worker进程处理并只能由这个worker进程完全处理。

Nginx在内部其实是维护了一个accept_mutex,其实就是一个锁,确保在某一时刻,一个请求只能被一个worker进程捕获。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

Nginx采用了异步非阻塞事件驱动的方式来处理请求的,只要我们设置好WORKER进程个数与CPU的亲缘性绑定,那么就能减少CPU在进程间切换所花费的时间以及切换带来的进程的保存/恢复现场,同时,由于Nginx中一个worker里面只有一个线程,也避免了线程的上下文切换。

第五,异步/非阻塞/事件驱动

我们知道,很多请求来了,他们大多需要读写数据,发生IO请求,此时程序就会发生中断,如果此时我们一直等待IO调用结束,才继续工作,那么这种就是阻塞的,那么很显然很多请求来了,都处于等待状态,CPU就将处于空闲状态,为了提供高并发的能力,Nginx采用的是非阻塞的方式。如果发生IO中断,那么你去做你的事情,但是过一段时间来看看IO调用是否结束,这就是非阻塞:你可以做更多的事情,但是你得时不时的检查中断状态,带来的开销也不小。

为了更高效,Nginx利用了LINUX的EPOLL模型(其他系统类似):

EPOLL模型,提供一种事件驱动机制,它可以监控多个事件是否准备好了,如果准备好了,那么就放入EPOLL队列中。这种机制是异步的。通过这样,WORKER进程只需要循环处理EPOLL队列中的请求,我们只需要在请求间不断切换,而这种切换是不需要付出什么代价的,通过这种循环处理已经准备好的请求,从而Nginx可以高效的处理高并发的问题。

(完)

vieyahn2017 commented 3 years ago

【Nginx】nginx的工作模式和信号量控制

nginx是一个多进程/多线程高性能web服务器,在linux系统中,nginx启动后会以后台守护进程(daemon)的方式去运行,后台进程包含一个master进程和多个worker进程(这个数量可以在nginx.conf配置文件中worker_processes这个参数设置),可以充分利用多核架构。nginx工作模式是以多进程的方式来工作的,当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。nginx在启动之后会有一个master进程和多个worker进程(默认是一个),多个worker子进程将监听同一个端口,并行处理请求。

master主进程主要用来管理worker进程,主要作用是:读取并验正配置信息,管理真正提供服务的worker进程,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。master进程不会对用户请求提供服务,而用户的请求则是worker进程来响应的。

nginx是通过信号来控制,比如关闭,重启等去控制nginx进程。nginx信号是属于nginx进程间的通信的一种机制,比如master主进程控制多个worker子进程,也是通过信号控制的,如下图。

worker 进程数应该设置为等于 CPU 的核数,高流量并发场合也可以考虑将进程数提高至 CPU 核数 * 2。

[root@localhost oa_workflow_test]# ps aux | grep nginx root 2381 0.0 0.0 47688 1464 ? Ss 6月01 0:00 nginx: master process /usr/local/nginx/sbin/nginx www 2383 0.0 0.1 50216 2304 ? S 6月01 0:00 nginx: worker process nginx 2624 0.0 0.3 775948 6800 ? S 6月01 0:00 php-fpm: pool www nginx 2625 0.0 0.3 775948 6800 ? S 6月01 0:00 php-fpm: pool www root 69028 0.0 0.0 114704 976 pts/1 R+ 12:24 0:00 grep --color=auto nginx [root@localhost oa_workflow_test]# /usr/local/nginx/sbin/nginx -s reload [root@localhost oa_workflow_test]# ps aux | grep nginx root 2381 0.0 0.1 48220 2728 ? Ss 6月01 0:04 nginx: master process /usr/local/nginx/sbin/nginx www 2383 0.0 0.1 50216 2304 ? R 6月01 0:02 nginx: worker process is shutting down nginx 2624 0.0 0.3 775948 6800 ? S 6月01 0:00 php-fpm: pool www nginx 2625 0.0 0.3 775948 6800 ? S 6月01 0:00 php-fpm: pool www www 69034 36.0 0.0 0 0 ? R 12:24 0:01 [nginx] www 69035 60.6 0.1 50548 2392 ? R 12:24 0:01 nginx: master process /usr/local/nginx/sbin/nginx www 69036 34.0 0.1 50548 2560 ? S 12:24 0:01 nginx: worker process www 69037 67.6 0.1 50548 2560 ? S 12:24 0:02 nginx: worker process www 69038 36.3 0.1 50548 2260 ? R 12:24 0:01 nginx: master process /usr/local/nginx/sbin/nginx root 69040 49.0 0.0 114708 980 pts/1 S+ 12:24 0:00 grep --color=auto nginx

Nginx支持以下几种信号选项:

TERM,INT: 快速关闭     
QUIT :从容关闭(优雅的关闭进程,即等请求结束后再关闭)
HUP :平滑重启,重新加载配置文件 (平滑重启,修改配置文件之后不用重启服务器。直接kill -PUT 进程号即可) USR1 :重新读取日志文件,在切割日志时用途较大(停止写入老日志文件,打开新日志文件,之所以这样是因为老日志文件就算修改的文件名,由于inode的原因,nginx还会一直往老的日志文件写入数据) USR2 :平滑升级可执行程序 ,nginx升级时候用      WINCH :从容关闭工作进程
  

Nginx信号控制语法:

  kill -信号选项 nginx的主进程号

  例如:从容关闭nginx服务

kill -QUIT nginx主进程号

vieyahn2017 commented 3 years ago

【Nginx系列】——Nginx基础篇(信号控制)

https://blog.csdn.net/jiadajing267/article/details/79221229 mandy@i 2018-01-31 20:15:42 1296 收藏 分类专栏: # 【Nginx系列】 【框架深入】 版权 前提 首先关于nginx总结是一个系列博客,博客内容的分布也会从浅入深。 在上篇博客中小编介绍了比较简便的nginx的安装教程,本篇文章nginx的一些基本应用。

Nginx简介 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP的代理服务器。Nginx由俄罗斯的Rambler.ru站点开发,而且官方测试Nginx可以支撑五万并发。

Nginx官网:http://nginx.org

在上篇博客中讲解了如何启动Nginx,而本文主要讲解Nginx运行后如何控制它,以便它的停止或者重新启动。

Nginx信号量 Nginx主要是通过信号量来控制Nginx,主进程编号默认写入文件nginx.pid中,可以通修改配置文件nginx.conf修改修改文件的名称。

Nginx主进程支持的信号如下:

信号量使用方式

kill -信号量 cat/usr/local/nginx/logs/nginx.pid

具体讲解

TERM,INT :kill -TERM(INT) nginx主进程号或者kill -TERM(INT) cat/usr/local/nginx/logs/nginx.pid,nginx的进程马上被关闭,不能完整处理正在使用的nginx的用户的请求,等同于 /usr/local/nginx -s stop

QUIT:kill -QUIT nginx主进程号 优雅的关闭nginx进程,在处理完所有正在使用nginx用户请求后再关闭nginx进程,等同于/usr/local/nginx -s quit

HUP:kill -HUP nginx主进程号 nginx进程不关闭,但是重新加载配置文件。等同于/usr/local/nginx -s reload

USR1:kill -USR1 nginx主进程号 不用关闭nginx进程就可以重读日志,此命令可以用于nginx的日志定时备份,按月/日等时间间隔分割有用

USR2:kill -USR2 nginx主进程号 nginx的版本需要升级的时候,不需要停止nginx,就能对nginx升级

WINCH:kill -WINCH nginx主进程号 配合USR2对nginx升级,优雅的关闭nginx旧版本的进程。

【总结】 利用Nginx这些信号量在不必关闭进程的时候就可以控制nginx的日志分割以及nginx的升级之类的内容,随着对Nginx的逐步深入更加觉得Nginx区区五万行的代码就能做到这么厉害,着实佩服了!