【笔记】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
【笔记】Nginx热更新相关知识的更多相关文章
- shell 脚本实战笔记(7)--集群网络相关知识和环境搭建
前言: 对网络相关的知识, 做下笔记. 包括IP地址A/B/C的分类, 静态地址的配置/DNS配置, 以及网卡相关信息查看. *) A/B/C/D类网络地址的划分 IP地址=网络地址+主机地址 或 I ...
- nginx 负载均衡相关知识
Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev ...
- Windows网络编程笔记4 -- Winsock 协议相关知识
Win32平台上的Winsock编程,Winsock是一个与协议无关的接口.以下协议是我们需要了解的: 网络协议的特征包括: 1. 面向消息 2. 面向连接和无线接 3. 可靠性和次序性 4. ...
- Android 热更新是如何实现的?
Android开发中,我们常常遇到热更新这个概念,而这个热更新具体是怎么实现的呢?今天在网上看到一个大神分享的热更新相关实现原理和实现代码,感觉灰常不错,分享给广大码农盆友look look . Cl ...
- Nginx 热部署和日志切割,你学会了吗?
上篇文章,我们已经安装好 Nginx,并且配置好 Nginx 文件后,这个时候我就需要操作 Nginx 的命令行了,这篇文章主要讲解 Nginx 命令行相关知识,并通过日常遇到的热部署.切割日志文件场 ...
- Unity3D热更新全书-重头再来
之前写了Unity3D热更新全书系列Blog 提出了下载.加载.脚本三个方面的开源类库 下载方面有EasyDown加载方面有GameObjParser脚本方面有C#Light另外有一个没有独立成库,但 ...
- 对C#热更新方案ILRuntime的探究
转载请标明出处:http://www.cnblogs.com/zblade/ 对于游戏中的热更,目前主流的解决方案,分为Lua(ulua/slua/xlua/tolua)系和ILRuntime代表的c ...
- 深入理解xLua热更新原理
热更新简介 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种热更新 ...
- 热更新解决方案--xlua学习笔记
一.热更新方案简介 在Unity游戏工程中,C#代码(编译型语言)资源和Resources文件夹下的资源打包后都不可以更改,因此这部分内容不能进行热更新,而lua代码(解释型语言)逻辑不需要进行预编译 ...
随机推荐
- 立一个Flag吧
以后在学习上遇到的问题以及解决办法,大部分都要记录在这里了,以备温故知新....就这样吧!
- java深拷贝的实现
深拷贝实现的工具类 package com.Utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStre ...
- git merge后如何撤销
merge后发现冲突太多,或者合并的分支代码并不是最新,那就直接撤销再合并好了. git reset --hard HEAD 用来撤销还没commit 的merge,其实原理就是放弃index和工作区 ...
- 白话skynet第二篇:skynet的通信调试pack和sprotol
今天来说说Skynet客户端和服务端网络通信的基础部分. Skynet当前版本.lua是skynet自带的5.3版本. 根据示例,我们可以知道.通信的步骤如下. 客户端按大小端打包成二进制. sock ...
- TypeError: Fetch argument 0.484375 has invalid type <class 'numpy.float32'>, must be a string or Tensor. (Can not convert a float32 into a Tensor or Operation.)
报错: TypeError: Fetch argument 0.484375 has invalid type <class 'numpy.float32'>, must be a str ...
- asp.net导入后台代码
public void Upload(string information){ int Bank = 0; for (int i = 0; i <Request.Files.Count; i++ ...
- setoolkit 制作钓鱼网页
由于是在虚拟机下实验,仅做示范 下载地址 git clone https://github.com/trustedsec/social-engineer-toolkit/ 终端输入setoolkit启 ...
- DotNetty网络通信框架学习之初识Netty
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- Java基础语法-Lambda表达式
1.Lambda表达式主要用于简写接口的操作等出现匿名内部类的地方,如下:我这里先定义一个Swim接口,以及它所定义的swim()方法 interface Swim{ void swim(); } 2 ...
- 类与对象 && 继承
以下是本人的对类与对象.继承的一些理解,如有错误之处万望谅解,如有朋友愿意指正,十分乐意,万分感谢! 类与对象 类与对象是学习编程的基础(大概吧),那么何为类?何为对象呢? 一.简 ...