首页 > 系统相关 >Nginx与Upstream之间产生大量TIME_WAIT连接的解决办法

Nginx与Upstream之间产生大量TIME_WAIT连接的解决办法

时间:2024-11-20 20:43:33浏览次数:1  
标签:Java TIME TCP Nginx Upstream http 连接

1. 现象

Nginx反向代理了一个Java服务,QPS大概是200,问题发生时的Nginx配置:

location / {
    proxy_pass http://192.168.3.4:18600;
}

在上游Java服务器上可以观察到大量(约2000个)的TIME_WAIT状态的网络连接

 

 从Nginx的error日志中还发现与Java服务器建立连接偶发失败的情况:

[error] 9208#0: *32907 connect() failed (111: Connection refused) while connecting to upstream, client: **.**.**.**, server: localhost, request: "POST /api HTTP/1.1", upstream: "http://**.**.**.**:18600/api", host: "**.**.**.**:8080"

2. 原因
由于QPS较高,Nginx与上游Java服务器建立的都是Http短连接,需要不停的创建和关闭TCP连接。而主动关闭TCP连接的一方需要等2MSL之后才会真正释放TCP连接,在2MSL之前连接的状态都是TIME_WAIT。

参考:TIME_WAIT状态产生的原因、过多的危害_爱吃芝麻球的博客-CSDN博客_time_wait连接过多的原因

由于每次上游Java服务在发送完响应报文后主动关闭了连接,所以作为主动关闭连接的一方,当并发量较高时就会产生大量的TIME_WAIT状态的连接。

3. 解决办法
解决的办法就是让Nginx与上游Java服务器之间通过Http 1.1的 Keepalive协议重用TCP连接,减少TCP连接数量
第一步: 修改location模块,添加http 1.1 协议头

location / {
    proxy_pass http://192.168.3.4:18600;
    
    # 添加http 1.1 协议头,这样上游Java服务就会启用keepalive,不会主动关闭TCP连接了
   proxy_http_version 1.1;
   proxy_set_header Connection "";
}

 

修改nginx配置重新生效后,发现上游Java服务器上的TIME_WAIT连接少了,但是Nginx服务器到上游Java服务器的TIME_WAIT连接却变多了。

原因在于Nginx自身没有复用到上游Java服务器的TCP连接,每次收到完整的响应报文之后就关闭连接了。

而这一次Nginx服务作为主动关闭TCP连接的一方,所以从Nginx服务器上TIME_WAIT的连接变多了。

第二步: 让Nginx主动重用TCP连接
Nginx的upstream模块中也有一个keepalive参数,但是这个参数与http协议中的keepalive参数的意义完全不同,upstream中的keepalive参数表示与上游服务建立的连接可以空闲的最大数量。

即如果在upstream模块中配置了keepalive参数,那么Nginx与上游服务之间建立的TCP连接就有了一个缓冲的池子,不再是用完立即释放了,而是可以有一个缓冲的池子可以放进去。keepalive参数的含义就是这个缓冲池子的最大值
参考:长连接 · Nginx 学习笔记 (gitbooks.io)

所以单独提取出一个upstream模块,并设置keepalive参数

upstream java_server {
    server 192.168.3.4:18600;
    
    # 设置可复用的tcp连接的空闲数量的最大值
    keepalive 50;
}

location / {
    proxy_pass http://java_server;
    
    # 添加http 1.1 协议头,这样上游Java服务就会启用keepalive,不会主动关闭TCP连接了
   proxy_http_version 1.1;
   proxy_set_header Connection "";
}

 

 

 

 

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_45145848/article/details/128854094

 

标签:Java,TIME,TCP,Nginx,Upstream,http,连接
From: https://www.cnblogs.com/fengjian2016/p/18559232

相关文章

  • SpringBoot+Docker +Nginx 部署前后端项目
    部署SpringBoot项目(通关版)一、概述使用 java-jar 命令直接部署项目的JAR包和使用Docker制作镜像进行部署是两种常见的部署方式。以下是对这两种方式的概述和简要的优劣势分析:1.1、使用 java-jar 命令直接部署项目的JAR包概述:通过 java-jar 直接部署项目的JA......
  • Nginx服务器配置---反向代理服务时proxy_pass的转发规则
    nginx是由俄罗斯开发的一款httpweb服务器,我们经常用这款服务器做负载均衡和反向代理。今天我们就来聊聊Nginx作为反向代理时,如何进行路由配置。假设你已经部署好Nginx了,我们进入Nginx安装目录,进入nginx.conf文件。找到http节点下的server节点,值是一个json。在json中有一个locat......
  • Mysql timestamp 类型时区问题
    1.问题描述当使用timestamp类型存储时间字段时,经常发生时区错误,比如相差8小时这样的问题。2.为什么会发生首先要介绍一个timestamp的存储结构与工作模式。2.1.timestamp的存储结构当在DB表结构中使用timestamp字段时,DB内部是以一个时间戳保存数据的,不存储具体......
  • LocalDateTime一些常用方法及示例
    packagecom.aaa.day04.api;importcom.aaa.utils.MyTool;importjava.time.*;importjava.time.format.DateTimeFormatter;importjava.util.Set;/***@author:nie6668888*@date:Createdin2024/11/1514:22*@description:*@modifiedBy:*@version:......
  • nginx 按日期生成log
    #!/bin/bash#获取昨天的日期date=$(date+%F-d-1day)#进入Nginx日志目录cd/usr/local/nginx/logs#创建备份目录(如果不存在)if[!-dbak];thenmkdir-pbakfi#移动日志文件到备份目录并重命名mvaccess.logbak/access_$date.logmverror.logbak/error_$date.l......
  • nginx 普通用户使用80端口启动nginx nginx: [emerg] bind() to 0.0.0.0:80 failed (13
    介绍当我们用普通用户执行启动nginx时,无法启动成功,报错nginx:[emerg]bind()to0.0.0.0:80failed(13:Permissiondenied)报错原因大家都知道默认情况下linux的1024以下端口是只有root用户才有权限占用,于是我们的tomcat,apache,nginx等等程序如果想要用普通用户来占用80端......
  • install .net 8 sdk/runtime on win7
    .net8sdk/runtimecanbeinstalledonwin7,if installvcredistribute: InstallMicrosoftVisualC++RedistributableVersion: https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistribut......
  • dotnet的Runtime和SDK的版本号差异
    摘要上周微软发布了NET9正式版本,我用官网介绍的方式为GitlabRunner制作包含NET9环境的映像,才发现Runtie和SDK的版本号差别。安装Dotnet的RuntimeDockerfile中语句如下:#使用官方脚本安装.NETSDK版本RUNwget-qO-https://dotnet.microsoft.com/download/dotnet/script......
  • 蓝易云 - 使用Debian、Docker和Nginx部署Web应用教程
    在Debian上使用Docker和Nginx部署Web应用是一种常见的配置方式。下面是一个简单的教程:安装Docker:在Debian上安装Docker,运行以下命令:apt-getupdateapt-getinstall-yapt-transport-httpsca-certificatescurlgnupglsb-releasecurl-fsSLhttps://download.docker.co......
  • Ingress Nginx基本认证
    IngressNginx基本认证1.使用htpasswd工具创建生成nginx认证用户1.安装htpasswd工具#yuminstallhttpd-y2.使用htpasswd工具生成测试用户名和密码#htpasswd-cauthadminNewpassword:Re-typenewpassword:Addingpasswordforuseradmin​#lsauthauth#c......