nginx 平滑重启 vs 平滑升级

1 篇文章 0 订阅
1 篇文章 0 订阅

1. nginx 架构

在总结了 nginx 配置以后,发现 nginx 可以做到平滑重启和升级,即在重启和升级的过程中服务不间断。于是怀着好奇的心情,开始了探索 nginx 的平滑重启和平滑升级是如何实现的。先解释下笔者对这两个名词的概念:

  • 平滑重启:针对的是更新 nginx 的 *.conf 文件
  • 平滑升级: 针对的是 nginx 服务的二进制文件更新,比如版本升级或者引入三方的模块重新编译

在正式理解这两个概念之前,需要先了解 nginx 的架构,架构如下图所示:

在这里插入图片描述

nginx 采用多进程的方式,包括一个 master 进程和多个子进程。其中 master 进程主要负责:加载配置项、启动工作进程及非停服务升级,worker 进程处理网络请求及响应( worker 进程基于异步及非阻塞的事件驱动模型提供服务)。

异步非阻塞的事件驱动模型单独解释

2. nignx 的 signal 支持

2.1 master 支持的 signal

TERM, INTQuick shutdown
QUITGraceful shutdown
KILLHalts a stubborn process
HUPConfiguration reloadStart the new worker processes with a new configurationGracefully shutdown the old worker processes
USR1Reopen the log files
USR2Upgrade Executable on the fly
WINCHGracefully shutdown the worker processes

2.2 worker 支持的 signal

There’s no need to control the worker processes yourself. However, they support some signals (意思是这些信号量无需手动处理,但是也能够被 worker 进程支持)

TERM, INTQuick shutdown
QUITGraceful shutdown
USR1Reopen the log files

3. nginx 平滑重启

3.1 nginx -s reload 命令

nginx -s reload 命令等价于kill HUP $(cat /usr/local/nginx/logs/nginx.pid) ,该信号会触发 master 进程完成以下工作:

  • 检查更新后的配置文件是否正确
  • 如正确,创建新的 worker 进程,新 worker 进程创建成功后,发送信号给旧 woker 进程使之优雅关闭。
  • 如错误,仍旧使用未更新之前的配置

笔者手动实验了一波,见下图:

在这里插入图片描述

  • 第一次 ps -ef | grep nginx 可观察到当前有一个 master 进程和两个 worker 进程。
  • 执行nginx -s reload 命令后,第二次 ps -ef | grep nginx ,观察到两个 woker 进程的进程 id 有变化。
  • 更改 nginx.conf 文件后,执行nginx -s reload 命令后,第二次 ps -ef | grep nginx ,观察到 worker 进程进程仅剩一个并且进程 id 有变化。

笔者在首次执行 nginx -s reload 的时候,并未变更任何配置,但还是重新产生了两个进程,很好奇这里为什么不检查一下配置有无变更?(待解答,后续补充……)

3.2 ngx_http_dyups_module

nginx reload 操作会影响到长连接,使用 dyups 模块可以避免 reload 操作。dyups(dyups means dynamic upstreams) 是github上一个nginx相关的开源插件,可以在不reload nginx的情况下动态更新upstream。

笔者没用上述插件,具体如何使用可以查看我们客服系统中使用tengine+dyups+consul 解决自动扩容缩容的问题

4. nginx 平滑升级

笔者翻看了 nginx 的源码,发现对 upgrade 指令的定义如下:

build:
	\$(MAKE) -f $NGX_MAKEFILE

install:
	\$(MAKE) -f $NGX_MAKEFILE install

modules:
	\$(MAKE) -f $NGX_MAKEFILE modules

upgrade:
	$NGX_SBIN_PATH -t

	kill -USR2 \`cat $NGX_PID_PATH\`
	sleep 1
	test -f $NGX_PID_PATH.oldbin

	kill -QUIT \`cat $NGX_PID_PATH.oldbin\`

4.1 平滑升级执行步骤

  • 更换新版本的二进制文件

  • 发送 SIGUSR2 信号给 master 进程,信号触发执行重命名 .pid 为 .oldbin(e.g. /usr/local/nginx/logs/nginx.pid.oldbin),执行新的二进制文件,即重启新的 master 和 worker 进程

在这里插入图片描述

  • 上图看到 2 组 nginx 实例在运行,共同处理接收到的请求,此时需要优雅停止旧 worker 进程,即发送 WINCH 信号给旧 master 进程

在这里插入图片描述

  • 观察一段时间后,发现只有新 worker 进程在提供服务,旧 woker 进程已经终止

在这里插入图片描述

  • 如上图所示,此时有两个 master 进程同时存在,笔者觉得 nginx 这里的设计很好,就好像铅笔后面的橡皮擦、购物后的七天无理由退货,给你足够的时间,让你有机会反悔。按照如下步骤执行

    • 1—— 发送 HUP 信号给旧 master 进程,它将重启 worker 进程
    • 2 —— 发送 QUIT 或者 TERM 或者 QUIT 给新 master 进程终止新 worker 进程
    • 3 —— 最后旧 master 进程将会移除 .oldbin 后缀,一切又恢复到反悔之前的状态啦
  • 如果升级的没有问题,发送 QUIT 信号给旧 master 进程,升级过程结束

在这里插入图片描述

5.思考

笔者的思考如下:

  • nginx 作为知名开源代码,提供的三方开源插件是真的多,只有你想不到,没有人家没写过的。
  • tengine 和 OpenResty 基于 nginx 开发,在 nginx 的基础上提供了更多因地制宜的定制化功能,比如上面的 dyups 已经合并到了 tengine 的代码仓库。
  • nginx 的源码是真的多啊…………

6.参考资料

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值