你好,谢你的解答。
那么下面我分别回应以下一个问题吧
1. nginx reload
ngx lua支持动态变化,但毕竟大家常用的是lua_code_off on;且在需要变更nginx code配置的时候,还是需要nginx reload;ngx lua动态变化适合 xxx_by_lua_file中的逻辑变化。
2. nginx stream 处理 is shutting down worker方案
方案1: 简单粗暴点
当worker处于is shutting down状态,一段时候后;shutting worker退出; 这个ngx stream lua 或者 通过修改nginx都可以达到目的
方案二: 根据协议是否结束来关闭当前connect;继而达到优雅退出 shutting woker
这个需要在nginx stream添加模块,且模块中需要知道proxy的协议,需要对协议进行解析; 这个nginx stream lua 和 修改nginx 也可以达到。但前提是需要根据proxy协议来定制模块。
方案三: 就是我之前提到的new nginx worker 接管 shutting down中的fd资源;此方案实现难度很大,但是一个与协议无关的 nginx stream reload优雅重启方案。
对nginx stream来说,不管四层负载的什么协议;它是无状态的。对于nginx来说,proxy一个连接;对应有client_fd 和 upstream_fd; 进程间将client_fd upstream_fd 传递给 new worker。在传递前现将对应的buffer转发完。
至于reload可能会有配置变动;是可以解决的。当前new worker接收到传递过来的client_fd upstream_fd;此关联的东西已经很少了。要么upstream_fd的upstream存在或者不存在。这个是可以解决的。
在 2016年11月10日星期四 UTC+8下午5:34:47,doujiang写道:
Hello
在 2016年11月10日 上午10:43,
<xianlian...@gmail.com>写道
:
你好,我用的是 nginx stream C模块,谢谢你的解答。
我的意识是nginx reload的时候,nginx new process可以直接接管old process中的长连接fd等数据结构。这样可以达到nginx stream reload无损重启。
看来你没有仔细看上面两位的回复
正如院生所说
你这个设想是不合理的,正是因为新旧 worker 进程除了 fd 之外还有很多很难保持一致的做法,才会在 reload 的时候启用 新的进程
如果照你这么说,直接在原始进程重新加载配置就完了不
另外你提到你用的 nginx stream,更新配置就需要 reload
如果你用 ngx-stream-lua-module,那么可以在 Lua 里可以做很多动态的变更,而不需要重启 nginx,当然还要看你需求
现在情况是nginx reload一段时间后,自己主动kill一直处于is shutting down process;这样会造成客户端的长连接直接关闭了。
正如春哥所说
处于 shutting down 的进程,需要自己去处理还未断开的连接
如你提到,你是给 mysql 做负载,你需要自己判断 query 的边界,在 query 之后结束 connection
在 2016年11月10日星期四 UTC+8上午6:35:02,agentzh写道:
Hello!
2016-11-09 3:20 GMT-08:00 <xianlian...@gmail.com>:
> 要是用nginx stream来给mysql做负载,nginx reload;那old process worker不是退不出了。
>
我不知道你这里是自己写的 nginx stream C 模块,还是用的 ngx_stream_lua_module.
无论是哪一种玩法,都可以在处理新的事件或请求前先检查一下当前 worker 是否已处于 exiting 状态,比如
ngx_stream_lua 支持 ngx_http_lua 的 ngx.worker.exiting() 接口:
https://github.com/openresty/lua-nginx-module#ngxworkerexiting
如果已处于 exiting 状态,就主动进行清理和收尾工作好了。这种事情只能你主动做了,因为 nginx 并不知道你的 TCP
请求和响应的边界,不知道何时可以安全地关闭当前连接。
Regards,
-agentzh