nginx反向代理下的长连接

一、nginx使用场景

大型应用架构中,一般会使用nginx反向代理,分为三层:

1.调用层,浏览器或APP;

2.中间层,反向代理nginx;

3.服务层,server一般是apche、tomcat

请求调用过程:

1.浏览器/app发起请求

2.DNS解析网址为ip地址

3.通过外网ip访问nginx

4.nginx发送请求给内网ip的server

上面架构,要想支持全链路的长连接,需要做到两点:

1.从client到nginx的连接是长连接;

2.从nginx到server的连接是长连接;

二、长连接设置

1.client到nginx的长连接:

由于目前浏览器默认使用HTTP/1.1,请求header中默认设置Connection:keep-alive,所以只需在nginx配置中做如下配置:

复制代码
http {
       keepalive_timeount 120s 120s;
       keepalive_requests 10000;
}

#语法
keepalive_timeout timeout header_timeout
第一个参数(timeout):设置keep_alive客户端(浏览器)连接在服务端(nginx端)保持开启的超时值(默认75s);值为0会禁用keep_alive客户端连接;
第二个参数(header_timeout):可选,在响应的header中设置值"Keep-Alive:timeout=time";通常可以不用设置;
keepalive_requests这个配置项用于设置一个keep-alive连接上可以服务的请求最大数量,当达到配置的最大请求数时,连接会被关闭,默认值为100.具体过程时指一个keep-alive连接建立之后,nginx会为这个连接设置一个计数器,记录这个长连接上已经接收并处理的客户端请求的数量,一旦达到设置的最大值时,nginx会强行关闭这个长连接,此时如果客户端有新请求,就需要重新建立新的长连接。
注:在QPS较高的场景下,服务端需要将keepalive_requests设置大一些,默认数值就不够了,否则服务端可能会出现大量的TIME_WAIT状态的TCP连接数异常!另外nginx(version 1.15.3)在Upstream内增加了keepalive_requests配置项,默认值也是100,也是需要手动设置,而且这两个数量可以不一致,一般服务端要设置的大些,因为多数情况是一个nginx代理对应多个服务端。

2.nginx和server的长连接

默认情况下,nginx访问后端都是用的短连接(HTTP/1.0)一个请求来了,nginx会新开一个端口和后端建立连接,后端执行完毕后主动关闭该tcp连接。为了让nginx和后端server(nginx称之为upstream)之间保持长连接,典型设置如下:

复制代码
http {
         upstream http_backend {
                  server 192.168.2.154:8080;
                  server 192.168.2.109:8080;
                  keepalive 32;                  # 长连接缓存池大小为32
                  keepalive_timeout  120s;       # 长连接失效时间
                  keepalive_requests 2000;       # 每条长连接最大复用请求数为2000
          }

        server {
                 location /http/ {
                 proxy_pass http://http_backend;
                 proxy_http_version 1.1;        # 启用HTTP/1.1版本与被代理服务器建立连接
                 proxy_set_header Connection "Keep-Alive";  # 设置发送被代理服务器请求头属性字段Connection
         }
 }

nginx 与被代理服务器间建立的长连接是通过启用 HTTP/1.1 版本协议实现的。由于 HTTP 代理模块默认会将发往被代理服务器的请求头属性字段 Connection 的值设置为 Close,因此需要通过配置指令设置请求头属性字段 Connection 的内容为"Keep-Alive"或者空值。
另外upstream中的keepalive_timeout和keepalive_requests参数与上面的含义一样,不做过多解析,需要重点关注keepalive参数,他的含义是指设置到upstream服务器的空闲keepalive连接的最大数,当这个数量被突破时,最近最少使用的连接将被关闭,另外这个参数不会限制一个nginx worker进程到upstream服务器连接的总数量,有点像线程池中的核心线程数。
注:keepalive参数设置一定要合理,尤其对于QPS比较高的场景,推荐做一下估算,根据QPS和平均响应时间大概计算出需要长连接的数量,尽量避免系统运行时产生连接数量的反复震荡,比如keepalive设置为10,前一秒系统qps较低,只需50个长连接,用完立马关闭其中50-10=40个连接,而后一秒系统qps突增,需要150个连接,空缺了150-10=140个连接,此时nginx不得不新建140个新连接来满足要求。

三、问题总结

综上所述,nginx反向代理的情况下,tcp长连接设置完成。在实际系统应用长连接的场景中,可能会出现大量TIME_WAIT的情况,这里简单做个总结:

1.导致nginx端出现大量TIME_WAIT的情况有两种:

a.keepalive_requests设置比较小,高并发下超过此值后nginx会强制关闭和客户端的长连接;(主动关闭连接后导致nginx出现TIME_WAIT)

b.keepalive设置比较小(空闲数太小),导致高并发下nginx会频繁出现连接数震荡,不停的关闭、开启和后端server的长连接;

2.导致后端server端出现大量TIME_WAIT的情况:

nginx没有打开和后端的长连接,即:没有设置proxy_http_version 1.1和proxy_set_header Connection "Keep-Alive",从而导致后端server每次请求后就关闭连接,高并发下就会出现server端的大量TIME_WAIT.

相关推荐
lingran__1 小时前
Linux 基础常用指令万字详解(上)|文件目录命令,结合底层原理剖析
linux·运维·服务器·后端·centos·linux基础指令
各类产品分享1 小时前
电力行业AR智能运维哪个品牌好
运维·ar·ar巡检
贾天佑忆月 迷失的昵2 小时前
客户端与服务器持续同步解析(轮询,comet,WebSocket)
运维·服务器·websocket
刘某的Cloud2 小时前
Galera Cluster mariadb 生产环境常见问题排查与运维指南
linux·运维·数据库·mariadb·集群高可用
70asunflower2 小时前
Linux 性能排查分析完全教程
linux·运维
zhangfeng11332 小时前
宝塔8 升级到 11导致 服务器无法访问外网dns失效了,无法访问bt.cn 解决方法 测试通过
运维·服务器
兵bing3 小时前
Docker Compose 配置文件归纳总结-千问
运维·docker·容器
INNOVIX稳石机器人4 小时前
从“存得下”到“管得活”:稳石四向穿梭车如何重塑密集仓储新逻辑?
大数据·运维
2401_858286114 小时前
OS81.【Linux】基于环形队列的多生产者-多消费者模型
linux·运维·服务器·环形队列
赵广陆4 小时前
Ubuntu Anaconda安装
linux·运维·ubuntu