nginx反向代理下的长连接

news/2024/12/21 16:55:22/

一、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;                  # 长连接缓存池大小为32keepalive_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.


http://www.ppmy.cn/news/1539461.html

相关文章

Redis主从复制机制详解

目录 一、主从复制介绍二、搭建主从复制三、主从复制流程四、关于Replication ID五、主从复制核心知识六、主从复制应用场景七、主从复制的注意事项八、读写分离实战 一、主从复制介绍 1、什么是主从复制? 2、为什么要使用主从复制? redis-server单点…

无mac电脑在苹果开发者上传构建版本

我们登录苹果开发者网站的后台,进入app store后,发现上架的页面需要上传一个构建版本。 这个构建版本的意思就是我们的应用二进制文件,是上架最重要的文件。但是在苹果开发者后台是无法直接上传这个文件的,它提示我们可以使用xco…

Android App系统签名

1.在AndroidManifest中添加 android:sharedUserId"android.uid.system" 2.获取系统签名 把以下所有文件放入同一个文件夹命名为sign 在Android系统源码中的\build\target\product\security目录下找到platform.x509.pem 和 platform.pk8两个文件; 在out/…

241015_把文件夹中所有的图片缩放为指定大小(缩放数据集)

241015_把文件夹中所有的图片缩放为指定大小(缩放数据集) 在制作自己数据集的过程中,我们经常会遇到image尺寸不统一的情况,以下是一段缩放到指定size的代码(代码中以512*512举例),修改路径即可…

科研绘图系列:R语言象限热图(quadrant heatmap)

文章目录 介绍加载R包数据韦恩图vennRHHO2对象其他系统信息介绍 在高通量数据分析中,比较两种实验条件下的差异表达(DE)模式是常见的。传统上,研究人员会设定一个截止值(例如p值=0.05或FDR 5%)。然而,采用这些特定的截止值似乎是武断的。例如,可能在这些特定截止值下几…

SpringBoot项目热部署-devtools

DevTools 会使用两个类加载器&#xff08;一个用于加载不变的类&#xff0c;一个用于加载可能会变化的类&#xff09;&#xff0c;每次重启只重新加载管理变化的类的加载器&#xff0c;因此会快很多 1.导入依赖 <dependency> <groupId>org.springframework.boot&l…

数据库迁移与版本控制:在Python项目中的实践

目录 引言 一、数据库迁移的必要性 二、数据库版本控制的基本原理 三、Alembic简介与实践 四、其他数据库迁移工具与比较 五、数据库迁移的最佳实践 六、结论 引言 在现代软件开发中&#xff0c;数据库扮演着至关重要的角色。无论是存储用户信息、交易记录还是业务数据&…

项目集成工作流,走审批流程,activiti,springboot,集成工作流,业务审批,驳回,会签,流程设计

前言 activiti工作流引擎项目&#xff0c;企业erp、oa、hr、crm等企事业办公系统轻松落地&#xff0c;一套完整并且实际运用在多套项目中的案例&#xff0c;满足日常业务流程审批需求。 项目源码配套文档获取&#xff1a;本文末个人名片直接获取。 一、项目形式 springboot…