[alibaba/tengine]开启session_sticky会话保持.后端无法复用长连接的问题.

2024-01-30 976 views
9

环境:

Tengine/2.2.0 (nginx/1.8.1)
CentOS release 6.3 (Final)

场景: 压测机 -> tengine -> tomcat , 前后端均开启了长连接. 且正常测试过长连接生效无误.压测机压测时也均开启了keep-alive长连接. 压测请求为一个极为简答的请求. 问题: 1.通过ip_hash进行会话保持的时候, 后端(tengine->tomcat)的长连接生效.而且TCP通道得到了复用.因为 ESTABLISHED连接数量稳定, TIME_WAIT 数量很少.. 2.通过session_sticky开启会话保持的时候,后端(tengine->tomcat)的长连接也生效了,但是却没有复用这个TCP通道.每一个请求从现象上看来都重新建立了TCP连接. 因为监控看到 ESTABLISHED 明显增大很多, 同时TIMC_WAIT状态的数量更是巨大,达到几W甚至10W以上,前面的场景只有几百的TIME_WAIT. 开启ip_hash的参数:

upstream srv_backend{
    session_sticky cookie=route;
    server 1.1.1.1:8080;
    server 2.2.2.2:8080;
    keepalive 50000;
    check interval=5000 rise=3 fall=3 timeout=5000 type=http;
    check_http_send "GET /monitor.html HTTP/1.0\r\nConnection: keep-alive\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

开启session_sticky的参数

upstream srv_backend{
    ip_hash;
    server 1.1.1.1:8080;
    server 2.2.2.2:8080;
    keepalive 50000;
    check interval=5000 rise=3 fall=3 timeout=5000 type=http;
    check_http_send "GET /monitor.html HTTP/1.0\r\nConnection: keep-alive\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

我现在不太确定,到底是因为session_sticky模块的问题.还是本身http协议原理上就是这样处理的. 为什么我用ip_hash的时候却没有问题?

回答

8

@jinjiu 谢谢,session_sticky本身功能用法都没有问题。目前问题是使用了session_sticky之后, tengine 对后端的http keepalive 连接异常, 并不对底层TCP连接进行复用的现象, 大量TIME_WAIT连接出现. 我在使用ip_hash的时候并不会出现这个现象.

3

我试了一下 session_sticky 也是支持长连接的。 麻烦你贴一下server段的配置,然后再time_wait出现时,netstat -ant |grep TIME_WAIT 看一下具体谁处于tw状态

4

抱歉,后续没有跟进回复这个问题,因为这是我们在为公司的活动,在对服务做压测调优性能。 场景是: 客户端(压测端) -> tengine -> tomcat. 出现大量time_wait连接,是 tengine -> tomcat 之间的连接,是出现 tengine这台机器上,应该是tengine主动关闭了这个连接。 由于当时活动紧急,也没有时间一直细究这个问题,只能不采用session_sticky继续压测。 server段配置有点多,我省略了一些确定没影响的参数. 其余upstream的配置在刚开头我有提供出。

server {
        # 省略了些无关的配置 (一些server_name, ssl证书配置等) #
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_header User-Agent;
        proxy_set_header  X-Forwarded-Proto $scheme;
        # 主要添加以下配置,支持长连接
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        # 然后就是具体的 location 配置了
        location  / {
                #里面没有过多的配置,基本只有proxy_pass 和log_format参数
                proxy_pass http://srv_backend;
                log_format xxxxx;
        }

当然,如果有其余的人也遇到这种问题,可以提出来。 如果只有我一个人有这种问题,我也没有头绪到底是哪里的问题了。 不过,这个问题已经过去很久了,如果没有什么好的办法的话,可以关闭这个issue.

1

我遇到的问题和你是一样的,交易路由是: 公网->tengine1 -> tengine2 -> tomcat , 开始发现问题是tomcat上面的timewait非常多,我在tengine2上面加了三行 keepalive proxy_set_header Connection "" proxy_http_version 1.1; tomcat的timewait马上下来了, 但是tengine2上面的timewait还是很多,想采用同样的方法在tengine1上面加keepalive来解决问题,可是没解决问题,反而导致来tengine1上面的timewait变多了,增加了好几倍,通过抓包发现tengine1和tengine2之间虽然报文有keepalive,但是没有复用tcp长链接,把tengine1上面的session_sticky去掉以后就engine1和tengine2通信就复用tcp链接来。