Nginx与Tomcat、Client之间请求的长连接配置不一致问题解决[转]
http://bert82503.iteye.com/blog/2152613
前些天,线上出现“服务端长连接与客户端短连接引起Nginx的Writing、Active连接数过高问题”,这个是由于“服务端使用HTTPs长连接,而客户端使用短连接”引起。这几天,发现Nginx与Tomcat之间也存在同样的问题,原因是两边的相关配置参数不一致引起的。(这是心细活!)
先说说服务为什么使用HTTPs长连接技术?有如下几个原因:
- 对响应时间要求较高;
- 服务走的是公网,客户端与服务端的TCP建立的三次握手和断开的四次握手都需要40ms左右(真实数据包计算出来的),共需要80ms左右;
- 每个接入方使用的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 512;
}
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;
}
}
[参考]
- nginx反向代理配置keepalive
- 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="512"
minSpareThreads="10"
acceptCount="768"
connectionTimeout="1000"
maxConnections="1280"
keepAliveTimeout="300000"
maxKeepAliveRequests="512"
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
至此,长连接验证完毕!
玩的开心!^_^
- Nginx与Tomcat的完整配置.tar.gz (6.7 KB)
- 下载次数: 0
- netstat_中文注释版.pdf (742.3 KB)
- 下载次数: 0
转载于:https://www.cnblogs.com/fx2008/p/4164236.html
Nginx与Tomcat、Client之间请求的长连接配置不一致问题解决[转]相关推荐
- 【部署】Nginx长连接配置
nginx upstream keepalive connections Nginx从 1.1.4 开始,实现了对后端机器的长连接支持,这是一个激动人心的改进,这意味着 Nginx 与后端机器的通信效 ...
- 直接访问静态图片_详解nginx和tomcat访问图片和静态页面的配置方法
概述 生产环境下,有时候需要访问图片,正常需要应用ftp.nginx等配套使用,但是有时候为了简化,可以用以下的两种简单的访问,说实话,就是为了偷懒,但是效果是能有的,这就行了,所以今天做这个简化版的 ...
- 配置nginx,Tomcat日志记录请求耗时
由于公司的业务比较特殊,对速度比较在意,客户最近反应我们的平台时间比较久,处理一个请求十秒左右才返回,领导要求找出原因,我想让nginx日志记录请求处理用了多长时间,后端处理用了多长时间,总共用了多长 ...
- dubbo消费者与提供者之间的tcp长连接
摘要 dubbo消费者同提供者之间的tcp连接是长连接形式,连接由消费方建立随机端口主动向提供者的dubbo端口发起连接请求,一旦连接建立,除非服务停止.网络异常,否则双方不会主动关闭tcp连接.也就 ...
- libcurl异步请求+http长连接池
由于公司项目,需要localhost的形式高并发的http访问本机服务,所以面临了两方面的问题: 1.http短连接会造成大量的time_wait,影响服务器的性能 2.libcurl easy同步接 ...
- Apache Web Server - httpd 的长连接配置
一 http协议的版本说明: 1 http/0.9 只能传输纯文本数据 2 http/1.0 引入了MIME机制 MIME是多用于互联网邮件扩展 multipurpose internet mail ...
- nginx配置长连接
2019独角兽企业重金招聘Python工程师标准>>> http {keepalive_timeout 20; --长连接timeoutkeepalive_requests 8192 ...
- java nio socket长连接_netty学习实战—实现websocket长连接和socket之间进程通信
netty学习-实现websocket长连接和socket之间通信 最近正在学习netty,跟着教程写了一个基于WebSocket的网页聊天室,对netty有了一定的了解,现在正好项目使用到长连接,选 ...
- nginx长连接与短连接性能对比
上一篇文章搭建了plg日志监控,本次准备看下目前集群的性能.对应机器如下:虚机4,前一后三,4台配置均为4核4g物理机为20核32g台式机. 先进行原始nginx配置的压测 nginx配置如下: us ...
- Android之间互相的录屏直播 --点对点传输(tcp长连接发送h264)(一)
前言 转载请注明出处 ,来自: 暂时两篇: (1) Android之间互相的录屏直播 –点对点传输(tcp长连接发送h264)(一) http://blog.csdn.net/baidu_335462 ...
最新文章
- NLP数据科学家不会告诉你的残酷事实
- Java Excel表格数据的导入导出
- Django进阶Model篇001 - mysql 数据库的配置
- linux下搭建cacti监控
- JSON学习笔记(四)- JSON.parse()
- 畅享网助力打造IT界的文化人
- php七牛分片上传_七牛视频切片方案 - 张小超fly的个人空间 - OSCHINA - 中文开源技术交流社区...
- 突发!Nginx 之父被拘留,原因竟然是“接私活儿”?
- Hive 导数据到本地(2种方式)
- 大数据学习之Hadoop任务输出到多个目录中
- 【剑指 offer】(二十四)—— 二叉搜索树的后序遍历序列
- Python: Shuffle()的作用
- vue 钉钉授权第三方WEB网站扫码登录功能
- 使用AOMEI无损数据的动态磁盘转基本磁盘
- CRM软件成功案例解析
- java tea collection_Javaの集合学习
- 2015.4.28 今天开博客了
- Python动态爬虫爬取京东商品评论
- portraiture2023智能磨皮修饰滤镜插件中文版
- 英语作业介绍一项发明计算机,计算机专业英语第1次作业.doc
热门文章
- 2021回顾 | AI 领域十大研究趋势及必读论文
- 【论文解读】ICLR2021 知识建模与信息抽取
- 字节跳动李航提出AMBERT!超越BERT!多粒度token预训练语言模型
- 【ACL2020-CMU-Google】MobileBERT:用于资源受限设备的任务无关“瘦版”BERT
- [CLS]预训练语言模型的前世今生[SEP]萌芽时代[SEP]
- 【工大SCIRLab】EMNLP 2019 跨语言机器阅读理解
- 周志华教授:长文详细教你如何做研究与写论文?
- Anaconda的安装和环境使用
- ASP.NET组件与开发之复合控件的事件处理
- 一文详解Python正则表达(3.X版本)