1.reload重载配置文件的真相
我们希望Nginx不停止服务的同时还能完成升级,reload重载文件配置就是一种升级方式.
我们希望能够平滑地新老过渡,将旧的配置文件更新为新的配置文件并且新配置文件被使用,
但有时候我们会发现Nginx的worker进程变多了,这其实是因为老的配置所运行的worker进程长时间
没有退出,我们使用stream做四层反向代理的时候,可能这种场景会更多,面对这些情况,
我们需要知道nginx -s reload到底做了什么.
在正常情况下是可以平滑更换配置文件的,但是也会出现异常情况,比如说一些请求出现
问题了,客户端长时间没有处理就会导致这个请求占用在老配置文件的worker进程上面,
这样这个老的worker进程就会一直存在,当然新的连接已经跑在新配置文件的worker子
线程中了,所以影响不会很大,唯一的影响就是下图中绿的旧的子进程长时间存在,但这也
只是影响已存在的连接,不会影响新的连接.
这时有什么办法来处理上面说的情况呢?
新的Nginx版本中已经提供了一个配置项work_shutdown_timeout(最长会等多久),也就是master进程
在起黄色的进程的时候,会添加一个定时器work_shutdown_timeout,时间到了以后如果worker子进程
如果还没有退出,立刻强制的把老的worker子进程退出.
我们还可能遇到更加罕见的场景,理解了reload流程(优雅地关闭旧的worker子进程和启动新的worker
子进程)之后,我们也许能更从容地面对这些棘手的问题.
2.热升级流程
不停机更新nginx二进制文件.
新的master进程是老的master进程的子进程,但新的master进程用的是新的binary文件来载入的.
3.优雅地关闭worker进程
优雅地关闭是针对worker进程的,因为只有worker进程才会处理请求,
如果我们直接关闭连接,会使得用户收到错误的提示,优雅地关闭是指
Nginx进程可以识别出当前连接没有正在处理请求,这时来关闭连接.
Nginx是不是一直能做到优雅地关闭子进程呢?
并不是的,比如说代理websocket协议时,在websocket协议后面进行
通讯的fream帧中,Nginx是不解析帧的,所以此时Nginx是无法知道处
理是否已经完成了的;再比如,Nginx做tcp和udp层的反向代理的时候,
它也没法知道一个请求究竟要经过多少次报文才算真正地结束,但是对于
http请求来说,Nginx是可以做到的,所以我们说的优雅地关闭针对的一般
是http请求:
优雅地关闭的期望流程:
1.设定定时器worker_shutdown_timeout,并设置标志位,告诉Nginx要进入优雅关闭的流程了;
2.关闭监听句柄,保证所在的worker进程不会再去处理新的连接了;
3.关闭空闲连接(Nginx为了保证自己对资源的利用是最大化的,经常会保存一些空闲的不断开的连接);
4.在循环中等待全部连接关闭(这一步可能时间非常长);
5.退出进程.
第四步中处理流程可能会超过worker_shutdown_timeout,但是只要配置了这个参数,一旦时间到了,
子进程就会立刻退出,这种情况也不算优雅关闭了.
在Nginx的使用过程中,我们需要考虑Nginx有没有能力去判定一个连接此时应该被正确的关掉,如果出现了
错误,有些模块或者有一些客户端不能正常地处理请求是,Nginx需要有一些措施比如说worker_shutdown_
timeout来保证Nginx老的worker进程可以正常地退出.