Unix 如何在不删除任何请求的情况下升级Nginx?
根据: 如果需要替换nginx二进制文件 使用一个新的(升级到 新版本或添加/删除服务器 模块),您可以不使用任何 服务停机-无传入 请求将丢失 我的同事和我试图弄明白:这是怎么回事?。我们知道(我们认为):Unix 如何在不删除任何请求的情况下升级Nginx?,unix,nginx,internals,Unix,Nginx,Internals,根据: 如果需要替换nginx二进制文件 使用一个新的(升级到 新版本或添加/删除服务器 模块),您可以不使用任何 服务停机-无传入 请求将丢失 我的同事和我试图弄明白:这是怎么回事?。我们知道(我们认为): 一次只能有一个进程监听端口80 Nginx创建一个套接字并将其连接到端口80 父进程及其任何子进程都可以绑定到同一个套接字,这就是Nginx可以让多个工作进程子进程响应请求的方式 我们还使用Nginx做了一些实验,如下所示: 向当前主进程发送一个kill-USR2 反复运行ps-ef
- 一次只能有一个进程监听端口80
- Nginx创建一个套接字并将其连接到端口80
- 父进程及其任何子进程都可以绑定到同一个套接字,这就是Nginx可以让多个工作进程子进程响应请求的方式
- 向当前主进程发送一个
kill-USR2
- 反复运行
以查看任何unicorn进程,以及它们自己的PID和它们的父PIDps-ef | grep unicorn
- 请注意,新主进程最初是旧主进程的子进程,但当旧主进程消失时,新主进程的ppid为1
我假设这是标准的Unix内容,但是我对进程、端口和套接字的理解非常模糊。有人能更详细地解释一下吗?我们的假设有错吗?我不知道nginx是怎么做到的,但基本上,它可以执行新的二进制文件,携带监听套接字和新的进程(实际上,它仍然是相同的进程,只是替换了在其中执行的程序)。侦听套接字有大量传入连接,只要启动速度足够快,就应该能够在溢出之前开始处理它们。如果没有,它可能会先fork,exec,然后等待它启动到可以处理传入请求的位置,然后通过某种内部机制在退出之前移交侦听套接字的命令(fork时继承文件描述符,两者都可以访问它)。注意您的观察结果,这看起来就像它在做什么(如果您的父进程死亡,您的ppid将重新分配给init,即pid 1) 如果它有多个进程在同一个侦听套接字上竞争接受(同样,我不知道nginx是如何做到的,也许它有一个分派进程?),那么您可以通过命令它们执行新程序来逐个替换它们,如上所述,但一次一个,这样就不会丢球。请注意,在这样一个过程中,永远不会有任何新的PID或父/子关系更改 至少,我想我可能会这么做,这是我的想法。有关详细信息:描述了用于TCP套接字的C库 我认为关键在于,当一个进程在持有套接字文件描述符时分叉后,父进程和子进程都能够对其调用accept() 这就是流程。Nginx,正常启动:
应该注意的是,根据nginx文档,在向旧主进程发送绞车信号之前,旧主进程和新主进程都在处理连接。