回答
收藏
分享
举报
nginx single process模式下(master_process off)不能很好的支持reload操作(reload后无法再提供服务)
提问于2020-06-04 21:54

浏览 1.6k

已修改于2023-03-17 17:58



写下您的回答
发表回答
全部回答(5)

按点赞数排序

按时间排序

single是单进程模式,而nginx是通过新启一个进程,由新进程重载nginx.conf文件,实现reload操作并提供服务的。因此single无法完成。

master/worker模式可以,因为master是父进程,worker是子进程,而父进程打开了80/443等端口,worker子进程可以共享。这样除了老的worker外,新的reload后的worker子进程也在监听相同的端口,这样老worker就可以在停止listen新连接后,服务完所有的老连接,优雅的退出。

具体你可以看下我的这篇文章:https://www.nginx-cn.net/article/70

赞同

6

回复举报

回答于2020-06-05 08:06



回复陶辉
回复
贺红杰回复了
谢谢陶老师。 还想确认一下:nginx single单进程模式是否实现完整的配置更新(reload),想要做到的效果是:不启动新的worker,而是让老的worker加载使用新的配置。 因为f-stack版本下的nginx,协议栈是与nginx worker进程绑定在一起的,一旦关闭老的worker进程,就会导致协议栈内部的连接信息丢失,然而又存在reload加载使用新配置的需求。 我觉得reload操作要保证的两个目标是:不直接丢失老的连接; 对新的连接即时提供服务。 这样的话,如果能够让老的worker的使用新的配置,相对来说是一个比较优雅的解决方案。但目前我还不能够确定这种方式是否能够做到,所以想再次请教一下陶老师。

2

回复举报

回答于2020-06-05 03:52



回复贺红杰
回复
陶辉回复了
@376:不可以,新配置目前只能用新worker进程

2

回复举报

回答于2020-06-05 06:05



回复陶辉
回复
贺红杰回复了
@31: 在目前nginx架构的基础上是否可行呢?如果不可行,存在哪些无法解决的问题? 如果让worker进程支持reload操作,目前我看到的问题点: - 创建新文件时存在多次打开问题 - 创建共享内在时存在多次创建问题 - 监听端口存在多次绑定失败问题

2

回复举报

回答于2020-06-05 06:29



回复贺红杰
回复
更多回复

我也考虑过这个问题,为什么配置改变以后一定要启动新的process来进行平滑处理。为什么不能在老的process中另外在内存中保存新的配置。 我现在的理解是,这样做对nginx来说可能复杂了。nginx本身框架和各个模块都需要额外的逻辑去处理新旧两份甚至多份内存中的配置,这样对于拥有大量第三方模块的nginx几乎是不可能的。而且现有的模块都需要为此做修改。

赞同

4

回复举报

回答于2020-06-19 09:25



回复皮皮鲁
回复
diff --git a/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/event/modules/ngx_epoll_module.c b/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/event/modules/ngx_epoll_module.c
index 76aee08..5883b04 100644
--- a/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/event/modules/ngx_epoll_module.c
+++ b/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/event/modules/ngx_epoll_module.c
@@ -625,6 +625,10 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
                    c->fd, op, ee.events);
     if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
+        if (ngx_errno == EEXIST) {
+            return NGX_OK;
+        }
+
         ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
                       "epoll_ctl(%d, %d) failed", op, c->fd);
         return NGX_ERROR;
diff --git a/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/os/unix/ngx_process_cycle.c b/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/os/unix/ngx_process_cycle.c
index 2696b62..7d48716 100644
--- a/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/os/unix/ngx_process_cycle.c
+++ b/src/openresty-1.13.6.2/bundle/nginx-1.13.6/src/os/unix/ngx_process_cycle.c
@@ -398,6 +398,24 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
             }
             ngx_cycle = cycle;
+
+            /*
+             * disable deleting previous events for the listening sockets because
+             * in the worker processes there are no events at all at this point
+             */
+            ngx_listening_t *ls = cycle->listening.elts;
+            for (i = 0; i < cycle->listening.nelts; i++) {
+                ls[i].previous = NULL;
+            }
+
+            for (i = 0; cycle->modules[i]; i++) {
+                if (cycle->modules[i]->init_process) {
+                    if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {
+                        /* fatal */
+                        exit(2);
+                    }
+                }
+            }
         }
         if (ngx_reopen) {


赞同

4

回复举报

回答于2020-06-18 15:12



回复贺红杰
回复

谢谢陶老师。

还想确认一下:nginx single单进程模式是否实现完整的配置更新(reload),想要做到的效果是:不启动新的worker,而是让老的worker加载使用新的配置。

因为f-stack版本下的nginx,协议栈是与nginx worker进程绑定在一起的,一旦关闭老的worker进程,就会导致协议栈内部的连接信息丢失,然而又存在reload加载使用新配置的需求。

我觉得reload操作要保证的两个目标是:不直接丢失老的连接; 对新的连接即时提供服务。


这样的话,如果能够让老的worker的使用新的配置,相对来说是一个比较优雅的解决方案。但目前我还不能够确定这种方式是否能够做到,所以想再次请教一下陶老师。

赞同

3

回复举报

回答于2020-06-18 15:12



回复贺红杰
回复

single process 现实情况中一般不会被使用。

我知道的single process的使用场景是nginx代码调试。

详细的用vscode调试方法可以参考:

https://github.com/zongzw-nginx/vscode-nginx


NGINX 配置中使用的配置参数和内容为:

 

参数:      -g "daemon off; master_process off;"

内容:

worker_processes 1;

 

events {}

 

http {

    server {

        listen 80;

 

        location / {

            return 200 "hello world!\n";

        }

    }

}

 


赞同

2

回复举报

回答于2020-06-11 21:08



回复宗兆伟
回复