【笔记】Nginx热更新相关知识
(以下学习笔记内容均摘自参考链接,仅供个人查阅)
1、inotify文件系统监控特性
Inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。inotify是Linux内核提供的一个文件系统变化通知机制,从2.6.13版本的内核开始提供,比如你在创建一个文件时它可以通知你哪个文件被创建了,删除文件时通知你哪个文件被删除了,修改文件时通知你哪个文件被修改了,关闭文件时哪个文件被关闭了,是可写关闭还是不可写关闭等等。
2、Nginx配置热更新
NginX采用Master/Worker的多进程模型,Master进程负责整个NginX进程的管理。主要包括:热更新、停机、日志重启等。
NginX的配置修改之后,在不影响当前服务的情况下进行更新。
信号: HUP
过程: 分为Master部分和Worker部分。
Matser进程:
1> 通过ngx_signal_hanlder解析出获取的信号,置ngx_reconfigure=1,标识Master要进行配置热更新操作。
2> 调用ngx_init_cycle初始化新的cycle(重新加载nginx.conf以及各模块的初始化)。
3> 调用ngx_start_worker_process启动新的Worker子进程,子进程标识just_respwan=1(NGX_PROCESS_JUST_RESPAWN)表示刚启动,区分新旧进程。
4> 调用ngx_start_cache_manager启动新的cache manager子进程和cache loader子进程。子进程标识just_respawn=1(NGX_PROCESS_JUST_RESPAWN)表示刚启动,区分新旧进程。
5> 睡眠100毫秒之后,调用ngx_signal_worker_process优雅的关闭老的worker、cache manager和cache loader进程。注意:只向just_respawn=0的进程进行发送信号。
Worker进程:
1> 通过ngx_signal_handler解析出为QUIT信号,置ngx_quit=1
2> 调用ngx_close_listening_sockets关闭监听端口。设置ngx_exting=1
3> 如果定时器红黑树中为空,执行ngx_worker_process_exit退出。
3. Nginx可执行程序热更新
Nginx可执行程序升级后,在不影响当前服务的情况下进行更新。
步骤1:信号:USR2
过程:
Master进程:
1> 通过ngx_signal_handler解析获取信号,置ngx_change_binary=1。
2> 调用ngx_new_binary=ngx_exec_new_binary 函数启动新的binary的NginX。(期间:需要进行老的环境变量的拷贝、socket句柄的传递、pid文件的拷贝等)。
此时,系统中同时存在两个Nginx(新、老)同时提供服务。
Woker进程:
无操作
步骤2:信号:WINCH
过程:
Master进程:
1> 通过ngx_signal_handler解析获取信号,置ngx_noaccept=1。
2> 置ngx_noaccepting=1,调用ngx_signal_worker_processes向子进程发送QUIT信号。即Worker进程优雅的退出。
如果此时没啥问题就可以直接关闭老的NginX Master进程了。(如果有问题,还有类似过程的回滚操作...)
3、Nginx可执行程序热更新流程步骤
步骤1、升级nginx二进制文件,需要先将新的nginx可执行文件替换原有旧的nginx文件,然后给nginx master进程发送USR2信号,告知其开始升级可执行文件;nginx master进程会将老的pid文件增加.oldbin后缀,然后拉起新的master和worker进程,并写入新的master进程的pid。
步骤2、在此之后,所有工作进程(包括旧进程和新进程)将会继续接受请求。这时候,需要发送WINCH信号给nginx master进程,master进程将会向worker进程发送消息,告知其需要进行graceful shutdown,worker进程会在连接处理完之后进行退出。
步骤3、经过一段时间之后,将会只会有新的worker进程处理新的连接。
注意,旧master进程并不会关闭它的listen socket;因为如果出问题后,需要回滚,master进程需要法重新启动它的worker进程。
步骤4、如果升级成功,则可以向旧master进程发送QUIT信号,停止老的master进程;如果新的master进程(意外)退出,那么旧master进程将会去掉自己的pid文件的.oldbin后缀。
nginx热更新相关信号
master进程相关信号
USR2 升级可执行文件
WINCH 优雅停止worker进程
QUIT 优雅停止master进程
worker进程相关信号
TERM, INT 快速退出进程
QUIT 优雅停止进程
什么是graceful shutdown
本文中的graceful shutdown是指server不再处理新的连接,但是进程不会立即退出,待所有连接断开后再退出进程。
总结一下在nginx 二进制文件热升级时用的命令
cd /usr/local/nginx
cp nginx nginx_bak
mv /data/nginx/nginx ./nginx #需要使用mv来更新二进制文件
./nginx -t #尝试启动,查看其加载配置文件等初始化功能是否正常
netstat -anp | grep -E "80|443" | grep nginx #检查连接状态
kill -USR2 `cat /usr/local/nginx/nginx.pid` #升级nginx可执行文件,此时会有两组nginx master和worker进程
kill -WINCH `cat /usr/local/nginx/nginx.pid.oldbin` #新的可执行文件启动ok,且能够正常处理数据流,告知老的master进程去通知其worker进程进行优雅退出
...
kill -QUIT `cat /usr/local/nginx/nginx.pid.oldbin` #待所有的老的nginx worker进程优雅退出后(处理完连接),停止老的master进程
TODO:nginx还会有依赖的so文件的热升级–其实更应该属于后台进程的so文件热升级流程,我在使用它的时候也踩过坑–主要原因还是操作不规范,对so其加载运行原理不够熟悉导致
热升级
实际上,静态语言后端server有一套固定的热升级(单进程)流程,其基本流程如下:
若需要支持热升级的是多进程,那么nginx的热升级过程是最值得参考的
1、通过调用 fork/exec 启动新的版本的进程,
2、子进程调用接口获取从父进程继承的 socket 文件描述符重新监听 socket
3、在此过程中,不会对用户请求造成任何中断。
nginx的热升级流程也是类似,只不过由于nginx工作是多进程,故它会先启动新版本的一组master/worker进程;然后停止老的worker进程,让其不处理连接,由新的worker进程来处理连接;升级完毕后,即可退出老的master进程,热升级完成。
4、Nginx upstream中 backup备份服务器的作用
Nginx 的 upstream 配置的时候,可以配置备份服务器 backup。
upstream backend {
server 192.168.198.128:8080 weight=1;
server 192.168.198.128:8090 weight=4;
server 192.168.198.128:8091 backup;
}
backup : marks the server as a backup server. It will be passed requests when the primary servers are unavailable.(标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。)
这意思就是,只有当你的服务器挂掉的时候才会使用备份服务器,正常情况下不会访问到备份服务器。
在所有正常服务器都挂掉时,系统依然高可用,这就是备份服务器的用处!
5、《Kubernetes集群中的Nginx配置热更新方案》原理:
Nginx自身是支持配置热更新的,通过nginx -s reload命令可以实现这一点。我们要实现的就是:当Kubernetes集群中的Service发生变化时,比如新创建一个Service或删除了一个Service,这些Service在Nginx反向代理中的路由配置需要同步更新并生效。因此,这个过程的场景大致如下:
5.1管理员通过命令或程序通过API操作K8s集群创建或删除Service;
5.2监听API Server Event的某个程序获取该Event,并从API Server读取最新Service数据,重新生成/etc/nginx/conf.d/default.conf;
5.3 /etc/nginx/conf.d/default.conf文件的变动触发文件变更事件,监听该事件的脚本调用“nginx -s reload”命令实现Nginx的配置热更新。
6、Nginx Proxy
nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
See Automated Nginx Reverse Proxy for Docker for why you might want to use this.
Usage
To run it:
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
Then start any containers you want proxied with an env var VIRTUAL_HOST=subdomain.youdomain.com
$ docker run -e VIRTUAL_HOST=foo.bar.com ...
参考链接:
inotify
https://baike.baidu.com/item/inotify/8361039
inotify -- Linux 2.6 内核中的文件系统变化通知机制(2005年)
https://www.ibm.com/developerworks/cn/linux/l-inotifynew/
inotify-tools命令使用讲解(安装及监控例子)
https://www.cnblogs.com/wajika/p/6396748.html
Nginx中文文档
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_core_module.html#server
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_upstream_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_proxy_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_index_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_access_module.html
http://tengine.taobao.org/nginx_docs/cn/docs/control.html
NginX进程管理-热更新
https://blog.csdn.net/huzelin1008/article/details/43193991
nginx-proxy
https://github.com/jwilder/nginx-proxy
http://jasonwilder.com/blog/2014/03/25/automated-nginx-reverse-proxy-for-docker/
Kubernetes集群中的Nginx配置热更新方案
https://tonybai.com/2016/11/17/nginx-config-hot-reloading-approach-for-kubernetes-cluster/
利用 Nginx 负载均衡实现 Web 服务器更新不影响访问
https://blog.csdn.net/liyongshun82/article/details/52787115
从nginx热更新聊一聊Golang中的热更新(上)
https://blog.csdn.net/qq_15437667/article/details/83513457
nginx多进程模型之配置热加载
https://blog.csdn.net/brainkick/article/details/7176405
HAProxy文档
https://cbonte.github.io/haproxy-dconv/1.8/intro.html
HAProxy用法详解 全网最详细中文文档
http://www.ttlsa.com/linux/haproxy-study-tutorial/
https://www.cnblogs.com/puremans/p/6428644.html