Nginx 信号控制

小夏 科技 更新 2024-01-31

在生产环境中,nginx 一般采用一个主进程和多个工作进程的模式,其中主进程不需要处理网络事件,不负责业务的执行,而只是对工作进程进行管理,以实现重启服务、平滑升级、替换日志文件等功能, 和配置文件实时生效,同时使用工作进程提供服务,如静态文件服务、反向**等功能。

那么nginx是如何实现master重启服务的,平滑升级,日志文件替换,配置文件实时生效呢?此外,主进程如何实时通知工作进程重启服务、平滑升级、替换日志文件、可配置文件生效?答案是信号。 下面我们来看一下nginx是如何结合**做到上述的。

因为nginx使用信号来实现平滑升级、日志文件替换、配置文件实时效果、重启服务等功能,所以nginx启动过程中使用的信号会注册到操作系统内核中,其**实现如下:

int ngx_cdecl

main(int argc, char *const *ar**)

初始化信号*

if (ngx_init_signals(cycle->log) != ngx_ok)

ngx init signals() 的实现方式如下:

ngx_int_t

ngx_init_signals(ngx_log_t *log)

ngx_signal_t *sig;

struct sigaction sa;Linux 内核使用的信号。

遍历 signals 数组,将所有 nginx 支持的信号*注册到内核

for (sig = signals; sig->signo != 0; sig++)

return ngx_ok;

从 ngx init signals() 函数的实现中,我们可以看到 nginx 通过调用 sigaction() 将支持的信号注册到操作系统内核中,当内核捕获到对应的信号时,会调用 ** 函数进行信号处理。 从**中可以看出,其实nginx支持的所有信号对应的处理程序都是一样的,即ngx信号hanlder()。 在这个函数中,nginx 中的信号会根据锁的信号设置一个对应的全局变量,然后在主进程的处理循环中根据这个全局变量执行相应的动作,后面会描述。

一般来说,当 nginx 进程(包括 master 进程和 worker 进程)已经在环境中运行时,所谓的平滑升级、日志文件或配置文件的替换实时生效等管理功能。 那么nginx是如何从命令行控制这些特性的呢?nginx 的做法是启动一个新的 nginx 进程,将相应的控制信号发送到环境中已经存在的主进程,以便现有的服务可以执行相应的动作。 那么,新的 nginx 进程如何向环境中已有的主进程发出信号呢?其**实现如下:

int ngx_cdecl

main(int argc, char *const *ar**)

"nginx -s xxx"*/

if (ngx_signal)

从实现中可以看出,新的 nginx 进程在执行后返回退出,因为这个新启动的进程是用来发送信号的。 那么,新进程如何向现有主进程发出信号呢?答案是通过终止系统调用。 一般来说,有两个步骤:第一个是获取存储在nginx中的正在运行的master进程pid 文件中的 pid,即 ngx 信号 process() 函数的作用,实现如下:

ngx_int_t

ngx_signal_process(ngx_cycle_t *cycle, char *sig)

ssize_t n;

ngx_pid_t pid;

ngx_file_t file;

ngx_core_conf_t *ccf;

u_char buf[ngx_int64_len + 2];

获取核心模块中存储的配置项的结构指针*

ccf = (ngx_core_conf_t *)ngx_get_conf(cycle->conf_ctx, ngx_core_module);

ngx_memzero(&file, sizeof(ngx_file_t));

file.name = ccf->pid;CCF->PID 是 nginxPID 文件。

file.log = cycle->log;

以可读的方式打开 nginx。PID 文件。

file.fd = ngx_open_file(file.name.data, ngx_file_rdonly,ngx_file_open, ngx_file_default_access);

读文件 * n = ngx 读文件(&file, buf, ngx int64 len + 2, 0);

if (ngx_close_file(file.fd) == ngx_file_error)

if (n == ngx_error)

删除结束控制字符*

while (n-- buf[n] == cr ||buf[n] == lf))

将字符串转换为数字以获取主进程 pid*

pid = ngx_atoi(buf, +n);

封装终止系统调用的信令功能*

return ngx_os_signal_process(cycle, sig, pid);

其次,在获取到正在运行的 master 进程的 pid 后,调用 kill 命令将新的 nginx 进程携带的信号发送给正在运行的 master 进程,这也是 ngx os 信号 process() 函数的功能,实现如下:

ngx_int_t

ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_pid_t pid)

ngx_signal_t *sig;

遍历 nginx 内核支持的信号,找到与名称相同的信号,并通过 kill 系统。

调用向主进程发送信号。

for (sig = signals; sig->signo != 0; sig++)

ngx_log_error(ngx_log_alert, cycle->log, ngx_errno,"kill(%p, %d) failed", pid, sig->signo);

return 1;

至此,新的nginx进程的任务完成,然后返回退出,那么接下来运行中的master进程会发生什么呢?这涉及到主进程的工作循环。 我们知道 master 进程并不向外界提供服务,而是专门用来管理 worker 进程的,那么在 nginx 中是如何实现的呢?

如前所述,nginx 通过启动一个新进程向主进程发送信号,因此主进程正在等待信号到达工作循环。 信号到达后,会触发信号处理功能,然后检测信号的相应标志位置,然后在主进程中检测相应的标志进行相应的处理。 在讨论主进程如何处理特定信号之前,让我们先看看主进程对哪些信号感兴趣,如下所示:

上面**中的chld信号不是由新的nginx进程发送的,但是操作系统内核在检测到子进程正在退出时,会向父进程(即master)发送chld信号,然后master进程会对此进行进一步分析,这就是ngx reap children()的功能。 在 ngx master process cycle() 中,我们可以看到 master 首先将自己感兴趣的信号添加到阻塞自身的信号集合中(通过 sig 块调用 sigprocmask(),然后在这些操作后调用 sigsuspend() 暂停自己,等待信号集中的信号发生,唤醒自己, 然后在信号发生后根据全局变量(见上表)进行相应的处理,处理流程图如下:

从主进程的工作循环中,我们可以看到,当主进程接收到相应的信号并完成自己的处理过程时,会通过ngx signal worker processes()向工作进程发送相应的信号。 例如,在收到退出信号后,主站会向所有 worker 子进程发送退出信号,通知 worker 优雅退出(所谓优雅,其实就是处理现有连接,不接受新连接),并为监听器关闭套接字句柄。 那么,工作进程会对哪些信号感兴趣,当它从主进程接收到相应的信号时会发生什么呢?这就是工人工作周期的意义所在。 在 worker 进程中,在接收到 master 发送的信号后,我们也会看到 worker 对哪些信号感兴趣,并在引入 worker 工作周期之前设置相应的全局变量,具体如下:

除了上述三个信号之外,在工作进程的工作循环中还可以看到另一个全局变量 NGX 激励。 只有一个地方会设置此标志,即在收到退出信号后。 NGX Quit 只会首次将 NGX Exciting 设置为 1。 为什么?因为当 worker 收到退出信号时,它知道它需要优雅地关闭进程,即完成对现有连接的处理并不再接受新连接,NGX Exciting 表示退出状态,即仍有尚未处理的连接。 以下是工作进程的工作原理:

这里只是对主进程和工作进程的信号处理过程的简要说明,对于详细的处理过程,如平滑升级、配置文件的实时效果等,你还是需要阅读**才能更好地梳理细节。

相似文章

    Docker 01 Nginx 容器部署,创建 docker 容器后修改挂载目录

    搜索 nginx 图像。root hongpon docker 镜像,查看当前可用的镜像。repository tag image id created size hello world latest caaac months ago .kb tomcat latest fbadc months a...

    Nginx服务器动态缓存机制及性能提升技术

    NGINX是一款高性能的Web服务器和反向服务器,广泛用于构建高并发 高性能的网络应用。为了进一步提高nginx服务器的性能,引入了动态缓存机制。本文将详细介绍 NGINX 服务器的动态缓存机制和性能提升技巧,包括缓存策略 缓存配置 缓存刷新和失效 缓存性能监控等,帮助您充分利用 NGINX 服务器...

    轨道交通信号与控制研究生方向

    轨道交通信号与控制是轨道交通系统的重要组成部分,负责列车运行的安全 高效 准确控制。轨道交通信号与控制专业主要方向如下 .信号系统 信号系统是轨道交通信号控制系统的核心,负责列车 车站 线路等的信息传输 处理和控制。信号系统的研究内容主要包括 信令系统基础知识。自动列车控制。自动站控制。自动生产线控...

    如何控制自己的情绪而不被情绪所控制?

    控制情绪是一项重要的心理技能,有助于保持身心健康并改善人际关系。这里有一些方法可以帮助你控制你的情绪,避免被它们控制。认知重建 学会检查和调整自己的思维模式。试着以更积极 理性的方式看待事物,避免过于悲观或消极的想法。情绪识别 学会识别和理解你的情绪。了解您当前的情绪状态是愤怒 焦虑还是抑郁可以帮助...

    信号差 没有信号?HUAWEI Mate X5 灵犀通信技术,让你随时在线

    我在地铁上和同事说话,但我的声音突然断断续续 和家人 在一起,却因为电梯和地下车库,画面卡住了 乘坐高铁的时候,我和队友一起开着黑车,却突然卡住了,失去了机会.你有没有被这些问题困扰过?虽然随着城市化进程的推进,在日常生活中却出现了很少的信号盲区。然而,由于各种复杂环境和个体因素的影响,绝大多数手机...