Nginx进程管理和重载原理详解


Posted in Servers onApril 22, 2021

进程结构图

Nginx是多进程结构,多进程结构设计是为了保证Nginx的高可用高可靠,包含:

  • master进程:父进程,负责worker进程的管理
  • worker进程:子进程,worker进程一般配置与服务器CPU核数相同,worker进程用来处理具体请求。
  • cache进程:也是子进程,包括cache manager和cache loader进程,主要是反向代理做缓存使用。

注:多进程相对于多线程之所以能够保证高可用与高可靠是因为进程间地址空间是独立的,进程间的任务不会相互影响,相对多线程更加耗费CPU资源。而多线程共享一个进程的地址空间,其中一个线程任务失败会影响到其它线程任务。

Nginx进程管理和重载原理详解

图3-1 Nginx进程结构图

假设我们的Nginx服务的用户是nginx,我们可以使用如下命令查看当前运行的Nginx服务的master进程和worker进程,而且可以看到4个worker进程的父进程ID都是master的进程ID(1325)。

[root@master ~]# ps -ef | grep nginx | grep -v grep | grep -v php-fpm
root       1325      1  0 11:28 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      1332   1325  0 11:28 ?        00:00:00 nginx: worker process
nginx      1334   1325  0 11:28 ?        00:00:00 nginx: worker process
nginx      1335   1325  0 11:28 ?        00:00:00 nginx: worker process
nginx      1336   1325  0 11:28 ?        00:00:00 nginx: worker process

Nginx进程管理和重载原理详解

图3-2 一个master进程与四个worker子进程

我们可以通过 lsof -i:nginx端口号 来查看我们的master和worker进程。

[root@master ~]# lsof -i:80
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   1325  root    6u  IPv4  22282      0t0  TCP *:http (LISTEN)
nginx   1332 nginx    6u  IPv4  22282      0t0  TCP *:http (LISTEN)
nginx   1334 nginx    6u  IPv4  22282      0t0  TCP *:http (LISTEN)
nginx   1335 nginx    6u  IPv4  22282      0t0  TCP *:http (LISTEN)
nginx   1336 nginx    6u  IPv4  22282      0t0  TCP *:http (LISTEN)

信号量管理

Linux的信号量管理机制

信号是进程间通信方式之一,典型用法是:终端用户输入中断命令,通过信号机制停止一个程序的运行。

我们可以通过给进程发送信号来管理我们的进程,kill -l命令可以查看linux支持的信号量

Nginx进程管理和重载原理详解

linux信号量

一共有64号信号量,主要需要弄清如下几个:

kill -1 $PID:(SIGHUP)重新加载进程,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件;

kill -2 $PID:(SIGINT)中断(通Ctrl+C);

kill -3 $PID:(SIGQUIT)从键盘输入的退出(ctrl-\);

kill -9 $PID:(SIGKILL)立即杀死进程,无论当前程序处于什么状态;

kill -10 $PID:(SIGUSR1)$USR1和$USR2都是留给用户自定义的信号量;

kill -12 $PID:($IGUSR2)

kill -15 $PID:(SIGTERM)正常停止一个进程;

kill -17 $PID:(SIGCHLD)父子进程通信的信号量,父进程可以fork()出很多子进程,子进程挂掉会给父进程发送信号;

kill 可将指定的信息送至程序。预设的信息为 SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用 SIGKILL(9) 信息尝试强制删除程序。程序或工作的编号可利用 ps 指令或 jobs 指令查看。

kill -l # 查看所有能够支持的信号
kill PID
# 杀死一个进程
kill 1024
# 杀死多个进程 进程号之间用空格隔开
kill 1024 2048
# kill -9 表示立即强制结束进程
kill -9 1024

注:Ctrl+C:停止终端中正在运行的进程,Ctrl+C可以比较有好地中止终端中正在运行的程序(进程)

利用信号量管理Nginx进程

管理Nginx进程可以这些方式:master进程worker进程命令行

使用信号量管理master和worker(不推荐使用发送信号量的方式来管理worker进程,worker进程应该交给master进程来管理和维护)。

Master进程

监控worker进程

  • CHLD

管理worker进程

接收信号

  • TERM、INT
  • QUIT
  • HUP
  • USR1
  • USR2
  • WINCH

示例:

通过kill命令杀死master进程

kill -s SIGTERM 1325

通过kill命令让Nginx重新读取文件,这样会关闭就得worker进程,生成新的worker进程,master进程(ID)依旧保持不变

kill -s SIGHUP 1325

Worker进程

接收信号

  • TERM、INT
  • QUIT
  • USR1
  • WINCH
  •  

虽然可以,但是不推荐使用信号量方式直接管理worker进程,worker进程应该交给master进程来管理和维护

示例:

使用kill命令杀死一个worker进程,这样会杀死一个worker进程,linux会杀掉的worker进程的父进程(master进程)发送SIGCHLD信号量,所以master进程监测到我们某一个子进程可能出了问题,会启动一个新的worker进程,维护worker进程的数量。

kill -s SIGTERM 1332

命令行

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

可以使用nginx -h查看帮助命令

[itbsl@master ~]$ nginx -h
nginx version: nginx/1.18.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/nginx-1.18.0/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

参数说明:

  • -?,-h:查看帮助
  • -v:查看Nginx版本
  • -V:查看Nginx版本和编译选项
  • -t:检查配置文件语法是否正确
  • -T:检查配置文件语法是否正确,并打印
  • -q:在检查配置文件时不显示非错误消息
  • -s:给master进程发送信号,可以发送:stop、quit、reopen、reload
  • -c:指定配置文件
  • -g:设置配置文件之外的全局指令

配置文件重载原理

我们知道了可以通过给nginx的master进程发送SIGHUP信号,或者使用nginx -s reload命令来达到重新载入配置文件,从而使nginx平滑升级。那我们执行这样一个命令之后,对nginx本身来说背后发生了什么事情呢,它是如何保证新老请求如何平滑过渡的?

reload重载配置文件的流程

  • 向master进程发送HUP信号(reload命令)
  • master进程检查配置语法是否正确
  • master进程打开监听端口(在修改配置文件的端口情况下,可能)
  • master进程使用新的配置文件启动新的worker子进程
  • master进程向老的worker子进程发送QUIT信号
  • 旧的worker进程关闭监听句柄,处理完当前连接后关闭进程

如果用图示来描述的话大概如下图所示

Nginx进程管理和重载原理详解

nginx -s reload

图示解析:

1.左边绿色的状态是执行nginx -s reload命令之前的状态,按照我个人主机的配置时一个master进程和4个worker子进程。

2.为了模拟执行nginx -s reload命令后原来的worker进程会处理完请求后再被杀掉,我模拟一个需要很久才能处理完任务并响应的接口,是的,我在代码里sleep 15秒,也就是说这个接口响应需要15秒,时间弄长点方便我们来观察中间态,注意,在执行reload命令前请求该接口

<?php
    sleep(15);
    echo json_encode(['msg' => 'hello world']);die();

3.我们已经知道了master进程会把任务交给worker子进程处理,目前只有一个任务,所以当前只需要一个worker进程需要处理任务。

4.执行reload命令,master进程会创建4个(与你配置有关)新的worker进程(我上图中的黄色worker进程),关闭掉旧的空闲worker进程(绿色worker进程),而正在处理请求的旧worker进程不会立即关闭,而是会等请求处理完毕就关闭。

5.剩下的最后一个旧worker进程任务处理完毕也被关掉,最后剩下的都是使用新nginx.conf配置产生的新worker进程,可以看下面的这张图,那个处于is shutting down的旧worker进程就是因为处理上面sleep 15秒的任务接口还没处理完毕,所以依然能够被看到。

Nginx进程管理和重载原理详解

总结

到此这篇关于Nginx进程管理和重载原理的文章就介绍到这了,更多相关Nginx进程管理和重载原理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Servers 相关文章推荐
Nginx 502 Bad Gateway错误原因及解决方案
Mar 31 Servers
使用Docker容器部署rocketmq单机的全过程
Apr 03 Servers
nginx搭建NFS网络文件系统
Apr 14 Servers
nginx实现多geoserver服务的负载均衡
May 15 Servers
ubuntu下常用apt命令介绍
Jun 05 Servers
CentOS7环境下MySQL8常用命令小结
Jun 10 Servers
win server2012 r2服务器共享文件夹如何设置
Jun 21 Servers
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
Jul 15 Servers
Nginx报404错误的详细解决方法
Jul 23 Servers
Windows server 2016服务器基本设置
Aug 14 Servers
windows server2012 R2下安装PaddleOCR服务的的详细步骤
Sep 23 Servers
详解Apache SkyWalking 告警配置指南
Apr 22 #Servers
apache基于端口创建虚拟主机的示例
Apr 22 #Servers
Nginx使用X-Accel-Redirect实现静态文件下载的统计、鉴权、防盗链、限速等
Apr 04 #Servers
Nginx工作原理和优化总结。
利用Nginx代理如何解决前端跨域问题详析
Apr 02 #Servers
Nginx URL重写rewrite机制原理及使用实例
Apr 01 #Servers
nginx限制并发连接请求数的方法
Apr 01 #Servers
You might like
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
PHP类的特性实例分析
2016/09/28 PHP
thinkPHP批量删除的实现方法分析
2016/11/09 PHP
php 如何设置一个严格控制过期时间的session
2017/05/05 PHP
PHP调用其他文件中的类
2018/04/02 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
JS在TextArea光标位置插入文字并实现移动光标到文字末尾
2013/06/21 Javascript
Javascript基于AJAX回调函数传递参数实例分析
2015/12/15 Javascript
jQuery遍历DOM元素与节点方法详解
2016/04/14 Javascript
微信小程序 for 循环详解
2016/10/09 Javascript
React Native实现地址挑选器功能
2017/10/24 Javascript
浅谈Vue的加载顺序探讨
2017/10/25 Javascript
vue--vuex详解
2019/04/15 Javascript
vue实现路由切换改变title功能
2019/05/28 Javascript
leaflet加载geojson叠加显示功能代码
2020/02/21 Javascript
用Python的urllib库提交WEB表单
2009/02/24 Python
python中精确输出JSON浮点数的方法
2014/04/18 Python
Python学习入门之区块链详解
2017/07/25 Python
Python基于多线程实现ping扫描功能示例
2018/07/23 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
微信公众号token验证失败解决方案
2019/07/22 Python
python numpy之np.random的随机数函数使用介绍
2019/10/06 Python
Python要如何实现列表排序的几种方法
2020/02/21 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
使用CSS3制作响应式导航菜单的方法
2015/07/12 HTML / CSS
Adobe Html5 Extension开发初体验图文教程
2017/11/14 HTML / CSS
绿色美容,有机护肤品和化妆品:Safe & Chic
2018/10/29 全球购物
应届生文秘专业个人自荐信格式
2013/09/21 职场文书
企划主管岗位职责
2013/12/12 职场文书
奠基仪式策划方案
2014/05/15 职场文书
技术经济专业求职信
2014/09/03 职场文书
小学五一劳动节活动总结
2015/02/09 职场文书
银行求职信怎么写
2019/06/20 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang
Python数据可视化之Seaborn的安装及使用
2022/04/19 Python
vue-cli3.x配置全局的scss的时候报错问题及解决
2022/04/30 Vue.js