nginx -s reload的真相

nginx -s reload 的流程

当我们使用nginx -s reload 命令之后(或者用kill -HUP $master_pid),nginx首先会检查配置文件的合法性,通常我们要使用nginx -t来检查,应该养成这种好习惯。如果配置文件不合法,将不会加载新的配置。接下来master使用新配置监听新的端口(如果有新的端口监听),加载新的功能,启动新的worker进程以处理接下来的新请求,master会向老的worker进程发送QUIT信号,老的worker进程处理完当前的连接后结束进程。这里注意一个点就是需要处理完当前连接后才能结束进程,这也就是我们用ps -ef |grep nginx 有时候能发现worker进程数比我们设置的数量多的原因。特别是用nginx反向代理一些长连接的服务的时候最常见。例如代理mysql、redis,亦或是websocket这种有持续探测帧的服务。

虽然nginx reload能在不停止服务的情况下加载新的配置。但是原先建立好的连接需要重新建立,特别是nginx开启http1.1中的keepalive的情况,那么reload之后,客户端回发起一个新的连接,三次握手需要重新建立,服务器上维护的客户端、服务端的双边信息需要销毁重新建立。如果是一个不繁忙的nginx倒也没什么,如果是一个非常繁忙的承载着十万百万级别连接的nginx,这就意味着一个很大的开销。在reload的时候,服务器的负载会进一步升高。针对这个问题,有个开源项目nginx-upsync-module使用nginx动态从consul或者etcd中同步上游服务器而不用reload。四层反向代理的项目是nginx-stream-upsync-module

留下评论