我有一个Nginx服务器,不断处理高负载的请求。 我希望能够改变服务器的configuration文件并以零停机时间dynamic重新加载它。
我在shell中运行以下行:
httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=1 --num-calls=10
而当它发送请求我重新加载我的nginxconfiguration。 我已经尝试了以下两个选项:
sudo nginx -s reload sudo kill -s HUP [pid]
它们都会导致httperf返回一些错误。 平均而言,在两个好的请求之后,httperf退出并打印它的日志,并附有以下相关的行:
Errors: total 1 client-timo 0 socket-timo 0 connrefused 0 connreset 1
我已经在许多地方看到,重装应该是无缝完成的,没有停机时间,但从testing中我看起来不一样。
我的问题是:
在此先感谢帮助,期待看到一些有见地的答案。
要了解以下答案,需要一些背景:
我是否以错误的方式进行testing?
是的,你的testing有些不正确。 问题是你的testing使用PERSISTENT连接来发送10个请求。 您可以通过运行以下testing轻松检查它,并且不会有任何连接重置(因为每个连接只发送一个请求):
httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=10 --num-calls=1
为什么我得到这个连接重置?
如果你看看nginx的文档 ,你会发现这个:
旧工作进程接收到一个closures命令,停止接受新的连接,并继续服务当前的请求,直到所有这样的请求被服务。 之后,老员工stream程退出。
这是真的,但文档没有提到持续连接发生了什么。 我在旧的邮件列表中find答案。 在当前运行的请求被服务之后,nginx会通过向客户端发送[FIN, ACK]来发起closures持久连接。
为了检查,我使用WireShark和configuration服务器与一个简单的工人,请求睡5秒,然后回复。 我用下面的命令发送请求:
httperf --server=127.0.0.1 --port=80 --uri=/ --num-conns=1 --num-calls=2
发布前面提到的命令后,我重新加载nginx(当它处理第一个请求)。 这里是由WireShark嗅探的包:
nginx reload被执行了。 这是okey,该服务器没有发送任何响应第二个请求。 根据TCP连接终止 :
已经终止的一方不能再发送任何数据到连接,但另一方可以。 terminal方应继续读取数据,直到另一方终止。
接下来的问题是客户端收到来自服务器的紧密连接信号后,为什么会发生4093?
可能这是答案 :
我要说的是POST与FIN同时发生,即客户端发送POST,因为它的TCP堆栈没有处理来自服务器的FIN。 请注意,数据包捕获是在系统处理数据之前完成的。
我不能评论这一点,因为我不是networking专家。 也许其他人可以给出更有见地的答案,为什么第二个请求被发送。
UPD以前链接的问题是不相关的。 询问有关问题的单独问题。
有没有解决这个问题?
正如邮件列表中提到的那样:
HTTP / 1.1客户端需要处理keepalive连接closures,所以这不应该是一个问题。
我认为应该在客户端处理。 如果连接被服务器closures,客户端应该打开新的连接并重试请求。
我实际上需要一个负载平衡器,我可以dynamic地添加和删除服务器,任何更好的解决scheme,适合我的问题?
我不知道其他服务器,所以不能在这里build议。
只要你的客户可以正确处理连接,应该没有任何理由阻止你使用nginx。