赞
踩
在http1.1中可以配置服务器端开启keepalive与客户端保持长连接进行优化,这里不过多解释。
我们在nginx.conf配置
- upstream favtomcat {
- server 192.168.80.112:8080;
- keepalive 20;
- }
- keepalive_timeout 65s;
- keepalive_requests 100;
keepalive_timeout:65s ##设置nginx开启keepalive,超时时间为65秒,也就是说:如果客户端65秒内没有后续的请求过来,nginx就会断掉这个TCP连接,设置为0表示禁用keepalive。
keepalive_requests :100 ##设置长连接能够处理请求的次数,100表示:一个长连接nginx最多处理100次请求就会关闭。
keepalive : 20 ##这个值必须设置,默认为0. 设置每个worker可以保持长连接空闲时的最大连接数。
这里需要特别解释一下,假设nginx有100个请求需要访问Tomcat,那么会建立100个连接,如果双方都支持keepalive,那么这100个连接都是长连接(可以复用那种的),当请求结束后,nginx会立马销毁 80个(100-20),只剩下20个长连接,这20个长连接在Tomcat的keepAliveTimeout时间到期后由Tomcat方关闭。
Tomcat的 keepAliveTimeout这个值可以设置大一些,性能会很好,比如设置个10分钟,20分钟的。
完事大吉,我们来测试。
192.168.80.110 Nginx
192.168.80.112 Tomcat
192.168.80.1 客户端Chrome浏览器
我们在浏览器疯狂刷新Nginx ,为了让浏览器启动最多的连接,我放了一大推的图片,并且图片URL后面加随机数,防止浏览器缓存。
接下来我们通过命令 netstat -ntp | grep nginx 查看服务器TCP连接的情况,后面加了grep nginx是只看nginx的tcp连接。
可以看到浏览器启动了6个TCP连接来与加载资源,无论我们怎么刷新,连接数都不会变,这就是因为使用了Keeplive,所有的连接可以进行复用(请求多个资源),如果把nginx的keepalive设置为0,每次刷新都会使用新的TCP连接,这里会出现大量TIME-WAIT的连接。
上图可以看到,客户端已经与nginx启动了keepalive,复用TCP连接,起到了很大优化,看起来似乎很完美,但是让我们在tomcat的服务器上看看tcp连接情况。 我们使用命令 netstat -ntp
192.168.80.112 tomcat服务器上的截图,我只截取了一部分,实际出现大量的TIME_WAIT的tcp连接。也就是说 客户端与nginx连接时确实是用了keeplive,但是nginx与tomcat的连接却没有启动keeplive,每一次请求都新建一个tcp,用完一次就关闭没有复用,所以出现了大量的TIME_WAIT的TCP连接,如果流量稍微大一些tomcat服务器会因为tcp资源耗尽而宕机。
问题已经发现了,那么如何去解决这个问题呢~,首选要找出问题出现的原因。
1、为什么nginx与tomcat的连接是短连接而不是keepalive长连接?
下图是nginx官网上的一段话,说需要设置proxy_http_version为1.1 并且 Connection 头需要清空,也就是说nginx与tomcat之间是使用http1.0的短连接模式进行通讯的。
让我们通过抓包工具来分析一下nginx与tomcat到底是不是使用http1.0短连接模式通讯的。
可以看到80.1浏览器请求80.110nginx使用的是http1.1,而nginx请求tomcat使用的是1.0.
我们看192.168.80.1 到 192.168.80.110的包,使用http1.1,并且设置了keepalive头。
我们再来看192.168.80.110 到 192.168.80.112的包,使用的是http1.0 并且connection 设置了close,告诉tomcat 连接只用一次,用完即关。
通过上述分析,我们知道了 nginx代理tomcat默认使用http1.0短连接模式,挺坑啊,为什么不直接使用1.1呢。
接下来我们把配置文件加上,在看看效果,记得重启nginx,可以看到通讯已经使用了http1.1 的keeplive模式了。
我们在重新测试疯狂刷新我们的页面,每个几秒刷新1次,刷新5次试试看。
我们在nginx上查看tcp连接情况,一共12个tcp连接,其中6个是客户端与nginx的,另外6个是nginx与tomcat的。
我们在tomcat上查看tcp的连接情况。可以看到一共6个与nginx的tcp连接。这样我们nginx与tomcat也是keepalive长连接了。
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
通过shell统计tcp各种状态的数量
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。