`

[线上问题] Nginx与Tomcat、Client之间请求的长连接配置不一致问题分析解决

阅读更多

前些天,线上出现“服务端长连接与客户端短连接引起Nginx产生大量"TIME_WAIT"状态的线程”的问题分析解决”,这个是由于“服务端使用HTTPs长连接,而客户端使用短连接”引起。这几天,发现Nginx与Tomcat之间也存在同样的问题,原因是两边的相关配置参数不一致引起的。(这是细活!)

 

先说说服务为什么使用HTTPs长连接技术?有如下几个原因:

  1. 对响应时间要求较高;
  2. 服务走的是公网,客户端与服务端的TCP建立的三次握手断开的四次握手都需要40ms左右(真实数据包计算出来的),共需要80ms左右
  3. 每个接入方使用的IP就若干个,需要建立的请求连接有限。

使用长连接技术,可以大幅减少TCP频繁握手的次数,极大提高响应时间;同时,即使使用长连接技术,也不需要消耗很多的系统资源用来缓存sockets会话信息。

 

以下是在自己电脑上验证三者之间的长连接请求,连接存活时间都为5min

【环境】

操作系统:Ubuntu 14.04 LTS

Nginx:1.6.2

Tomcat:7.0.51

JDK:1.7.0_51

Client:HttpClient 4.3.5

 

【相关配置】

1. Nginx - 反向代理
nginx.conf:

http {
    ...

    ##

    # 与Client连接的长连接配置

    ##

    # http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests

    # 设置通过"一个存活长连接"送达的最大请求数(默认是100,建议根据客户端在"keepalive"存活时间内的总请求数来设置)

    # 当送达的请求数超过该值后,该连接就会被关闭。(通过设置为5,验证确实是这样)

    keepalive_requests 8192;

 

    # http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout

    # 第一个参数设置"keep-alive客户端长连接"将在"服务器端"继续打开的超时时间(默认是75秒,建议根据具体业务要求来,但必须要求所有客户端连接的"Keep-Alive"头信息与该值设置的相同(这里是5分钟),同时与上游服务器(Tomcat)的设置是一样的

    # 可选的第二个参数设置“Keep-Alive: timeout=time”响应头字段的值

    keepalive_timeout 300s 300s;

 

    ...

    include /etc/nginx/web_servers.conf;

    include /etc/nginx/proxy_params;

}

web_servers.conf:
upstream web_server {
    server 127.0.0.1:8080;

    # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

    # 连接到上游服务器的最大并发空闲keepalive长连接数(默认是未设置,建议与Tomcat Connector中的maxKeepAliveRequests值一样)

    # 当这个数被超过时,使用"最近最少使用算法(LUR)"来淘汰并关闭连接。

    keepalive 768;
}

server {

    listen 80;

    server_name lihg.com www.lihg.com;

 

    location / {

        proxy_pass http://web_server;

 

        ##

        # 与上游服务器(Tomcat)建立keepalive长连接的配置,可参考上面的keepalive链接里的"For HTTP"部分

        ##

        # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version

        # 设置代理的HTTP协议版本(默认是1.0版本)

        # 使用keepalive连接的话,建议使用1.1版本。

        proxy_http_version 1.1;

        # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

        # 允许重新定义或追加字段到传递给代理服务器的请求头信息(默认是close)

        proxy_set_header Connection "";

 

        proxy_redirect off;

    }

}

 

[参考]

  1. nginx反向代理配置keepalive
  2. keepalive for HTTP - Module ngx_http_core_module

 

2. Tomcat
conf/server.xml
    <!--
        maxThreads:由此连接器创建的最大请求处理线程数,这决定可同时处理的最大并发请求数(默认为200)
        minSpareThreads:保持运行状态的最小线程数(默认为10)
        acceptCount:接收传入的连接请求的最大队列长度(默认队列长度为100)
       
        connectionTimeout:在接收一条连接之后,连接器将会等待请求URI行的毫秒数(默认为60000,60秒)
        maxConnections:在任何给定的时间,服务器能接收和处理的最大连接数(NIO的默认值为10000)

        keepAliveTimeout:在关闭这条连接之前,连接器将等待另一个HTTP请求的毫秒数(默认使用connectionTimeout属性值)
        maxKeepAliveRequests:在该连接被服务器关闭之前,可被流水线化的最大HTTP请求数(默认为100)
       
        enableLookups:启用DNS查询(默认是DNS查询被禁用)
        compression:连接器是否启用HTTP/1.1 GZIP压缩,为了节省服务器带宽
        compressionMinSize:指定输出响应数据的最小大小(默认为2048,2KB)
        compressableMimeType:可使用HTTP压缩的文件类型
        server:覆盖HTTP响应的Server头信息
     -->
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="768"
               minSpareThreads="512"
               acceptCount="128"
              
               connectionTimeout="1000"
               maxConnections="1024"
               keepAliveTimeout="300000"
               maxKeepAliveRequests="768"
              
               enableLookups="false"
               URIEncoding="utf-8"
               redirectPort="8443"
               compression="on" compressionMinSize="1024" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json,application/xml"
               server="webserver" />

 [参考]

The HTTP Connector - Tomcat 7 Configuration Reference

 

3. Client

客户端HTTP "Keep-Alive"实现代码,请打开下一行的链接。

KeepAliveHttpClientsTest -> httpclient-x

 

【结果验证】

使用 "sudo netstat -antp | grep 80" 监控与Nginx相关的线程状态

 

netstat命令输出格式

Proto    Recv-Q             Send-Q               Local Address                     Foreign Address                  State              PID/Program name

协议     接收队列长度    发送队列长度     本地socket的地址和端口号  远程socket的地址和端口号  socket状态   进程id/进程名称

 

套接字(socket)状态

ESTABLISHED:含有一条已建立连接(connection)的socket

SYN_SENT:正在积极尝试建立一条连接的socket

SYN_RECV:接收到来自网络的一个连接请求

FIN_WAIT1:socket已关闭,同时连接正在关闭中

FIN_WAIT2:连接已关闭,同时socket正在等待远程终端的一个关闭请求

TIME_WAIT:socket正在等待关闭仍然在网络中的处理包

CLOSE:socket未被使用

CLOSE_WAIT:远程终端已经关闭,等待本地socket关闭

LAST_ACK:远程终端已经关闭,同时本地socket也关闭了。等待确认包

LISTEN:socket正在监听传入的连接

CLOSING:两边socket都已关闭,但仍然还没有我们所需要的发送数据

UNKNOWN:未知的socket状态

 

 

=====================

单个请求的线程状态

=====================

# 第1次请求,nginx分别与上游服务器(tomcat)、client互相建立1条连接

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:47272         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker (nginx -> tomcat)

tcp        0      0 127.0.0.1:80            127.0.0.1:53240         ESTABLISHED 1014/nginx: worker (nginx -> client)

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53240         127.0.0.1:80            ESTABLISHED 13845/java      (client -> nginx)

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47272         ESTABLISHED 10912/java      (tomcat -> nginx)

 

# 休眠10秒钟后,发起第2次请求

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:47272         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:80            127.0.0.1:53240         ESTABLISHED 1014/nginx: worker 

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53240         127.0.0.1:80            ESTABLISHED 13845/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47272         ESTABLISHED 10912/java      

 

# 超过keepalive存活时间(5min)后nginx已断开与上游服务器(tomcat)的长连接,同时与client连接进入关闭过程

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:80            127.0.0.1:53240         FIN_WAIT2   -                (nginx -> client)

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       1      0 127.0.0.1:53240         127.0.0.1:80            CLOSE_WAIT  13845/java      (client -> nginx)

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47272         TIME_WAIT   -               (tomcat -> nginx)

 

 

# 休眠7分钟后,发起第3次请求。nginx与上游服务器(tomcat)、client重新建立新的长连接(不同的端口号)

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:80            127.0.0.1:53242         ESTABLISHED 1014/nginx: worker (nginx -> client)

tcp        0      0 127.0.0.1:47274         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker (nginx -> tomcat)

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53242         127.0.0.1:80            ESTABLISHED 13845/java      (client -> nginx)

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         ESTABLISHED 10912/java      (tomcat -> nginx)

 

# 休眠10秒钟后,发起第4次请求

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:80            127.0.0.1:53242         ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:47274         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53242         127.0.0.1:80            ESTABLISHED 13845/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         ESTABLISHED 10912/java

 

# 请求刚结束后,nginx断开与client的长连接,但与上游服务器(tomcat)的长连接还打开着,直到超过keepalive存活时间(5min)后才会被关闭。若在keepalive存活时间内再次发起请求,nginx与上游服务器(tomcat)的长连接会被重用

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:47274         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker (nginx -> tomcat)

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53242         127.0.0.1:80            TIME_WAIT   -               (client -> nginx)

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         ESTABLISHED 10912/java      (tomcat -> nginx)

 

# 请求结束1分钟后,client到nginx的TIME_WAIT长连接也被释放

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:47274         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         ESTABLISHED 10912/java     

 

# 请求结束5分钟后,nginx断开与上游服务器(tomcat)的长连接

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         TIME_WAIT   -               (tomcat -> nginx)

 

 

========================

3个并发请求的线程状态

========================

# 第1次请求,nginx分别与上游服务器(tomcat)、client互相建立3条连接

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1010/nginx      

tcp        0      0 127.0.0.1:80            127.0.0.1:53245         ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:47279         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:80            127.0.0.1:53247         ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:47281         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:80            127.0.0.1:53246         ESTABLISHED 1014/nginx: worker 

tcp        0      0 127.0.0.1:47280         127.0.0.1:8080          ESTABLISHED 1014/nginx: worker 

tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      10912/java      

tcp6       0      0 :::8080                 :::*                    LISTEN      10912/java      

tcp6       0      0 127.0.0.1:53247         127.0.0.1:80            ESTABLISHED 13976/java      

tcp6       0      0 127.0.0.1:53245         127.0.0.1:80            ESTABLISHED 13976/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47281         ESTABLISHED 10912/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47280         ESTABLISHED 10912/java      

tcp6       0      0 127.0.0.1:53246         127.0.0.1:80            ESTABLISHED 13976/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47279         ESTABLISHED 10912/java      

tcp6       0      0 127.0.0.1:8080          127.0.0.1:47274         TIME_WAIT   -               

 

[参考]

netstat(8) - Print network connections, routing tables, interface statistics - Linux manual page

 

至此,长连接验证完毕!

 

 

玩的开心!^_^

分享到:
评论

相关推荐

    linux下Nginx+tomcat整合的安装与配置

    ### Linux下Nginx+Tomcat整合的安装与配置详解 在现代的Web服务器架构中,Nginx作为高性能的反向代理服务器和负载均衡器,常被用来与Tomcat等应用服务器配合使用,以提高网站的响应速度、稳定性和安全性。本文将...

    Nginx+tomcat配置集群负载均衡实例

    由于Tomcat处理动态内容的能力较强,但在处理静态资源时效率较低,因此通常与Nginx配合使用,让Nginx负责静态资源,Tomcat处理动态请求。 配置Nginx+Tomcat集群负载均衡的第一步是安装Nginx和多个Tomcat实例。在多...

    [线上问题] “服务端长连接与客户端短连接引起Nginx产生大量\"TIME_WAIT\"状态的线程”的问题分析解决

    本文讨论了在线上环境中,服务端长连接和客户端短连接配置不当导致Nginx服务器产生大量“TIME_WAIT”状态线程的问题,同时提供了问题的分析和解决方法。本文主要涉及的网络编程知识点包括长连接与短连接的定义和区别...

    Nginx+Tomcat+Memcached共享session集群配置

    通过以上配置,我们可以实现一个基于 Nginx、Tomcat 和 Memcached 的高效且可扩展的集群架构,该架构不仅解决了 Session 共享的问题,还大大提高了系统的并发处理能力和稳定性。在实际应用中,还需要结合具体的业务...

    Nginx + Tomcat 负载均衡配置详解

    **Nginx + Tomcat 负载均衡配置详解** 在现代互联网应用中,服务器的高可用性和性能优化是至关重要的。Nginx 和 Tomcat 的组合常常被用来实现这样的目标,其中Nginx作为反向代理和负载均衡器,而Tomcat作为Java应用...

    Nginx+tomcat+redis

    - **负载均衡**:Nginx可以基于多种策略(如轮询、最少连接、IP哈希等)分配请求到不同的Tomcat实例,从而实现负载均衡,提高系统的可用性和响应速度。 - **静态资源处理**:Nginx对静态文件(如CSS、JavaScript、...

    nginx+tomcat多域名配置

    - ** Sticky Session**:Nginx可以配置为将来自同一用户的请求始终转发到同一台Tomcat服务器,保持Session的一致性。 - **Redis共享Session**:在Tomcat和Nginx之间部署一个Redis服务器,将Session数据存储在Redis...

    windows下配置nginx反向代理tomcat

    ### Windows 下配置 Nginx 反向代理 Tomcat 在 Windows 环境下配置 Nginx 作为 Tomcat 的反向代理服务器是一项常见的任务,主要用于实现负载均衡、提高安全性及提升性能等目的。本文将从下载 Nginx 开始,详细介绍...

    nginx和tomcat的整合

    - **性能优化**:根据实际负载调整Nginx和Tomcat的相关配置,例如连接超时设置等。 #### 五、总结 通过上述步骤,可以实现Nginx与Tomcat的整合,从而达到高效处理静态和动态资源的目的。这种整合不仅提高了系统的...

    Nginx+Tomcat搭建负载均衡,实现网站请求的分发

    Nginx+Tomcat搭建负载均衡是实现网站请求的分发的常见解决方案。以下是该解决方案的详细知识点说明: 一、负载均衡的概念 负载均衡是指将网络请求分配到多个服务器上的技术,以提高服务器的响应速度和可用性。负载...

    nginx+tomcat反向代理安装配置

    在IT行业中,构建高效、可扩展的Web服务是至关重要的,而`nginx`和`tomcat`的结合使用就是一种常见的解决方案。`nginx`作为一款高性能的反向代理服务器和负载均衡器,常用于处理静态资源,而`tomcat`则作为Java应用...

    nginx和tomcat配置SSL和负载均衡配置

    ### Nginx 和 Tomcat 配置 SSL 与负载均衡详解 #### 一、Nginx 支持 SSL 的确认方法 Nginx 支持 SSL 加密是现代 Web 服务器的基本需求之一,确保数据传输的安全性。首先,我们需要确认当前安装的 Nginx 版本是否...

    nginx+tomcat服务器配置

    下面我的解决办法是在Internet和tomcat之间加一个nginx反向代理。 (此图片来源于网络,如有侵权,请联系删除! ) 基本结构 https请求发送到nginx,nginx将请求代理到tomcat nginx解决了单ip多域名的问题,多站

    Nginx与Tomcat

    在提供的`nginx_tomcat_demo`压缩包中,可能包含了一个示例的Nginx配置文件和一个简单的Java Web应用,用于演示Nginx与Tomcat的整合。通过查看这些示例,你可以更好地理解整合过程和配置细节。 总之,Nginx与Tomcat...

    windows服务器部署 nginx+tomcat+mysql服务器端部署 阿里云服务器部署及配置

    详细说明了windows服务器nginx+tomcat+mysql部署及配置(配置阿里云后台安全组,配置域名)很适合新手学习 附件中包含: 1.操作说明文档 2.操作录屏 3.安装所用到的软件安装包 1)Windows Server 2019 数据中心版 ...

    Nginx与Tomcat集群配置 Redis配置

    以下将详细介绍Nginx与Tomcat集群配置以及Redis配置的相关知识点。 ### Nginx的编译与安装 1. **安装编译环境**:在安装Nginx前,需要确保系统已经安装了必要的编译工具,如GCC、Make等。同时,可能还需要安装pcre...

    Nginx与tomcat 负载均衡

    Nginx与Tomcat的负载均衡 Nginx与Tomcat的负载均衡是指通过Nginx服务器来实现Tomcat集群的负载均衡,以提高系统的高性能和可扩展性。下面是实现负载均衡的详细步骤和知识点: 一、环境准备 * Nginx 1.8.0 * ...

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 nginx配置

    Nginx+Tomcat+Memcached实现tomcat集群和session共享 nginx配置

    nginx、tomcat安装免费ssl安全证书配置

    在互联网世界中,HTTPS协议是确保网站数据传输安全的重要手段,它可以加密用户与服务器之间的通信,防止中间人攻击。SSL(Secure Sockets Layer)安全证书是实现HTTPS的基础,而Nginx和Tomcat是两种常用的Web服务器...

Global site tag (gtag.js) - Google Analytics