[alibaba/tengine]nginx reload导致 http keepalive 模式连接断开

2024-06-26 13 views
8

在对nginx 进行性能测试,发现nginx reload 会导致 http keepalive 模式连接断开(http 1.0或者 http 1.1 connection:close 不存在这种情况),请问这个有什么好的办法处理?

回答

4

在对nginx 进行性能测试,发现nginx reload 会导致 http keepalive 模式连接断开(http 1.0或者 http 1.1 connection:close 不存在这种情况

这个是nginx的默认行为。 因为shuttingdown的worker需要尽快退出,而如果允许持续长连接服务请求会导致nginx长时间退出不了。注意正在服务的请求不会断开,但是请求处理完连接不会再被复用(keepalive),直接关闭了。

请问这个有什么好的办法处理?

需要改到nginx core,目前配置指令上没有方法可以支持

  • 前端keepalive处理

image

  • 后端keepalive处理

  image

1

如果直接把 ngx_terminate和ngx_exiting 场景设置连接保活,并且后端invalid 也去掉,这个有没有其他影响?比如这部分连接得不到释放什么的

2

应该只会导致连接一直复用下去,在连接被客户端/后端主动断开前 无法让nginx worker退出

5

一般keepalive 都会有timeout和 max keepalive requests ,对于http的keepalive 客户端应该保留的时间不会太长,我不知道阿里这边是怎么处理这个问题的,不知道ngx_terminate和ngx_exiting去掉后,会不会有其他异常的情况出现。。

6

一般我们用这个功能:http://tengine.taobao.org/document/core.html, 指定shuttingdown的进程再reload之后 指定时间 后退出(如果此时还有请求在处理,则被强制断开,会导致正在处理中的请求失败,但是一般非常少)

Syntax: force_exit exit_time;
Default: —
Context: main

force worker processes to exit after exit_time.

The force_exit support is not enabled by default. You should compile it explicitly:
0

force_exit 应该不能保证http 1.1 keepalive 不中断吧,force_exit应该是让websocket这种长连接在设定的时间里面强制关闭

5

force_exit可以保证,强制退出进程。

0

翻了下force_exit 代码,发现force_exit 只是为了在指定时间内强制退出进程,看样子跟http 1.1 keepalive reload 没太大关系吧?force_exit 只是在原来代码里面加了 ctx->tm <= 0 的时候进程退出,这个不能避免,如果把 ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel || ctx->tm <= 0 改成 ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel && ctx->tm <= 0 或许还有点效果吧?

ngx_force_exit_timer_handler(ngx_event_t *ev)
{
    ngx_force_exit_timer_ctx  *ctx;
     if (ev && ev->data) {
        ctx = (ngx_force_exit_timer_ctx *) ev->data;
        ctx->tm -= 1000;
         if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel
            || ctx->tm <= 0)
        {
            ngx_worker_process_exit(ctx->cycle);
            return;
        }
         ngx_add_timer(ev, 1000);
    }
}
3

发现force_exit 只是为了在指定时间内强制退出进程,看样子跟http 1.1 keepalive reload 没太大关系吧?

正在处理的请求会被强制退出掉(因为 到期退出进程,是直接exit(0)的)

4

那等于 force_exit其实也不能解决 nginx reload 会导致 http 1.1 keepalive 连接断开问题

6

可以用 msgsnd 将连接描述符发到其他 worker 的,与 @chobits 说的相同,如果要改就改到 nginx 核心了,每个 NGINX 版本维护会比较费劲。

1

可以用 msgsnd 将连接描述符发到其他 worker 的,与 @chobits 说的相同,如果要改就改到 nginx 核心了,每个 NGINX 版本维护会比较费劲。

赞同,不过msgsnd只能迁移fd(描述符),但是整个请求的其他状态(各种request数据结构)在nginx进程里几乎很难迁移。