`
xinlanzero
  • 浏览: 253049 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

glassfish下的性能调优:令人极度困惑的Max Connections参数

    博客分类:
  • J2EE
 
阅读更多

近日做性能调优,主要是针对web service,运行于glassfish之上。前期通过修改优化代码,基本搞定一些阻碍性能的问题,主要是代码层次的不合理。
之后还是发现性能上不去,而且表现明显不合理:tps只能达到2k,而服务器cpu只停留在10%附近,压力测试的客户端cpu也不高,20%-30%吧。反复thread dump后检查无果,不论是服务器端还是客户端的工作线程都算正常,没有发现线程/锁之类的问题。分析发现主要的症状是服务器端和客户端都压不上去,服务器端工作线程很空闲,客户端则忙于socket通讯及等待服务器返回。

于是开始怀疑问题可能出现在网络通讯上,一边跑压力测试,一边用netstat命令查看socket状态,很快发现问题,有大量多大数k的socket连接出现。感觉不正常,因为应该用的是长连接,按说正常情况socket连接数应该近似等于并发的线程数。测试工具为客户端soapUI,直接连接到运行在glassfish上的web service. soapUI是支持长连接的,glassfish也是支持长连接的。

做了一下验证,只开一个工作线程,跑了几个请求,通过抓包工具发现的确是只建立了一个连接,后面的请求都是跑在同一个socket连接上。试着增加http header Connection: Keep-Alive,发现和默认没有这个参数时表现一致。故意设置为Connection: close,则每次请求都是重新建立连接。因此排除http 是短连接的问题。

继续回头看socket状态,发现出现的多达数k的socket有很多都是处于TIME_WAIT状态,只有少数处于正常的ESTABLISHED状态。TIME_WAIT意味着是服务器端主动要求close socket的,在长连接并且不断有请求的情况下,服务器为什么会如此频繁的关闭连接呢?

试着只开一个压力测试的工作线程,tps大概100+的情况下看服务器端的socket情况,很快发现问题:先是建立一个socket,ESTABLISHED状态,然后大概2s左右重新建立一个新的socket,原有的这个状态转为TIME_WAIT,之后每隔2-3秒左右,都会有上诉的情况出现—-原有连接被放弃,重建新的连接。这样socket就成了1 + n的状态:1个ESTABLISHED + n个TIME_WAIT,一定时间后TIME_WAIT的socket开始逐个消失。

将压力测试的工作线程加到100之后,上述情况开始变的极度激烈,大量TIME_WAIT的socket被建立,数目直接上到1w,2w乃至36000,之后开始偶尔报错说无法连接。

问题基本就定位在这里了,为什么明明建立好了长连接,服务器端确总是会不断的关闭这些长连接导致无数的TIME_WAIT?

试着查找资料,调整参数并反复测试,最终发现和两个参数有关:

1. http.maxConnections

glassfish官网说明
https://metro.dev.java.net/guide/HTTP_Persistent_Connections__keep_alive_.html

HTTP keep-alive behavior can be controlled by the http.keepAlive (default: true) and http.maxConnections (default: 5) system properties. For more information, see Networking Properties

进入http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html 页面查看相关的系统属性,最后聚焦在http.maxConnections :

http.maxConnections (default: 5)
If HTTP keep-alive is enabled, this value is the number of idle connections that will be simultaneously kept alive, per-destination.

从说明上看,应该是max idle connection,和命名maxConnections不大符合,maxConnections感觉像是最多容许开这么多长连接。考虑默认值为5明显应该是max idle connection。

后面的测试验证,就是这个参数非常的致命,在修改为200之后,tps直接 *2。

返回来分析这个参数,默认最多容许有5个空闲长连接。考虑到100个工作线程,正常应该长连接数目也在100附近,考虑每次请求都要先申请一个连接,用完之后再放回,100个工作线程同时操作,很有可能同时将超过5个的连接返还给连接池。如果服务器简单的判断说多于5个连接然后就立即close并释放长连接,那么就会出现一方面连续释放长连接,一方面因为连接数不够不停的创建新的长连接。

换言之,当100个线程并发在连接池中进行申请连接/返还连接的过程中,连接池内的可用连接数是时刻变化的,实际的数目会有大的波动。而默认的最大空闲参数过小(默认才5)使得这个波动有极大的几率突破限制,从而造成连接池进行不必要的释放所谓过多的“空闲”连接。

glassfish中,对于这个参数的修改,非常简单,在jvm参数中增加新的一项”-Dhttp.maxConnections=250″,重启即可。

2. maxKeepAliveRequests

前面的调整,虽然达到了tps * 2的良好效果,但是使用netstat查看socket时,还是发现有非常多的TIME_TIME状态的socket,只是数目没有原来那么直上3w那么夸张,大概稳定在2000附近。

看来还是有其他的原因的,重新回头看当时只开一个线程测试的场景:一个线程连续提交,会出现1个ESTABLISHED + n个TIME_WAIT。

感觉上像是一个长连接上只要跑一段时间或者一定的请求,socket就会被服务器端关闭。修改测试方法,让每次请求之间等待一段时间,降低tps,发现关闭连接的时间间隔大为增加。

后来google到maxKeepAliveRequests这个参数,对于tomcat,apache等服务器都有支持,解释如下:

maxKeepAliveRequests:
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.

随即google到grizzly也有类似的系统参数可以设置这个maxKeepAliveRequests

-Dcom.sun.enterprise.web.connector.grizzly.maxKeepAliveRequests=-1
使用关键字”glassfish maxKeepAliveRequests”,发现glassfish还是有支持这个参数的,但是找不到具体设置的方法。后来在glassfish的控制台-> Configuration -> http service -> Keep Alive 下
发现了一个Max Connections参数,默认值250,解释为”Maximum number of connections in the Keep-Alive mode”,和maxKeepAliveRequests似乎完全不是一回事。

但是试着将这个参数修改为2500之后,非常惊讶的发现,见效了!单线程测试长连接释放的速度明显放慢,大体算了一下时间间隔和tpc,无论是之前的默认250还是现在新修改的2500都和测试结果
很合拍。开到100个线程测试,发现原有的2000附近的TIME_WAIT连接被降低到了大概300附近,明显改观。后面发现,可以用下面的参数直接设置:
asadmin set –user admin –passwordfile passwords.txt –port 47348 “server.http-service.keep-alive.max-connections=2500″

这里就有点奇怪了,从测试结果来看,这个参数的表现和maxKeepAliveRequests参数的功能是一致的,但是这个参数明明叫做Max Connections,而且旁边的注释”Maximum number of connections in the Keep-Alive mode”也证明了这点。很令人费解,并且这里的Max Connections前面的http.maxConnections有重名嫌疑而作用明显不同。

下面是一个简单的列表,其他情况相同下,分别修改者两个参数前后的对比:

keep-alive.max-connections http.maxConnections test result
250 5 TPS=650-700 TIME-WAIT=32600
250 200 TPS=1200 TIME-WAIT=300
2500 5 TPS=650-700 TIME-WAIT=32600
2500 200 TPS=1200 TIME-WAIT=300

最终的结果,还是比较理想的,修改了上述两个参数之后,cpu终于压上去了,tps也有了巨大的提升,而且TIME_WAIT的连接也大为减少。但是这两个参数的名称,注释和实际测试中的效果,都有名不副实的感觉,令人困惑。

后续更新:
1. 经同事提醒,有新的发现,maxKeepAliveRequests得以确认

http://docs.sun.com/app/docs/doc/820-4343/abefk?a=view
这里是sun的官方资料,其中对Max Connections 参数解释如下:
Max Connections

Max Connections controls the number of requests that a particular client can make over a keep-alive connection. The range is any positive integer, and the default is 256.

Adjust this value based on the number of requests a typical client makes in your application. For best performance specify quite a large number, allowing clients to make many requests.

因此可见这个”max connections”参数的确就是通常意义上的”maxKeepAliveRequests”。这里sun的命名不大合适,容易造成误解。
refer to:www.blogjava.net/aoxj/archive

本Blog文章除特别声明之外皆为原创文章,欢迎转载,转载请注明: 转载自JSSAY'S BLOG

本文链接地址: http://www.jssay.com/blog/index.php/2010/05/06/performance-tuning-glassfish-under-max-connections-is-extremely-confusing-parameters/

分享到:
评论

相关推荐

    glass 调优

    1. **GlassFish应用服务器调优手册**:该手册详细介绍了如何对GlassFish应用服务器进行调优,以便提升应用性能和服务器性能。调优手册是一个专业文档,通常包含了一系列针对特定软件产品进行性能优化的方法和技术...

    hk2-utils-2.4.0-b34-API文档-中英对照版.zip

    Maven坐标:org.glassfish.hk2:hk2-utils:2.4.0-b34; 标签:glassfish、utils、hk2、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...

    GlassFish 2.1.1QuickStartGuide

    性能调优:** - **JVM 参数调整:** 根据应用负载调整 JVM 的堆大小、垃圾回收策略等。 - **连接池配置:** 调整数据库连接池的最大连接数、空闲时间等参数。 - **缓存机制:** 实现应用层面的缓存机制来减少...

    glassfish4-jaas:Glassfish4.1 JAAS 示例

    在 Glassfish 4.1 中,JAAS 配置通常通过 `domain.xml` 文件进行,该文件位于域的配置目录下。你可以定义自己的 JAAS 配置,包括登录模块和相关的安全策略。 **3. 创建登录模块** 登录模块是实现特定认证逻辑的代码...

    Sun glassfish Performance Tuning Guide

    《Sun Glassfish性能调优指南》是一份详尽的技术文档,旨在帮助系统管理员、开发者和架构师优化Glassfish服务器的性能,确保其在各种负载条件下都能提供最佳的服务响应时间和资源利用率。 ### 核心知识点: #### 1...

    Sun Glassfish v3 Administration 2009/12 PDF

    - **线程池管理**:调整线程池参数以优化并发性能。 - **缓存策略**:合理利用缓存机制减少数据库访问频率。 5. **故障排除**: - **日志分析**:通过对日志文件的分析来定位问题。 - **监控工具**:使用如...

    Beginning Java™ EE 6 Platform with GlassFish™ 3: From Novice to Professional

    《初识Java™ EE 6平台与GlassFish™ 3:从新手到专业》这本书是为那些想要深入了解Java企业级应用开发的初学者和进阶者准备的。它全面覆盖了Java EE 6平台的核心技术和GlassFish服务器的使用,帮助读者从零基础开始...

    linux下实现glassfish自动启动

    在Linux环境下,Glassfish服务器的自动化启动是系统管理员和开发者常用的需求,这有助于提升服务器管理效率,确保服务的持续性和稳定性。Glassfish是Oracle公司提供的一个开源Java EE应用服务器,它支持各种Web应用...

    glassfish网络开发服务器

    7. **性能优化**:内置了JVM调优工具,可以分析和优化服务器性能,同时支持连接池和缓存管理,以提高响应速度。 8. **社区支持**:GlassFish拥有活跃的开发者社区,不断推动其发展和更新,提供各种插件、教程和问题...

    Glassfish安装和启动

    ### Glassfish安装与启动详解 #### 一、简介 GlassFish 是一款开源的应用服务器,它遵循Java EE标准,被广泛应用于开发、测试和生产环境中。本文档将详细介绍如何安装和启动GlassFish应用服务器。 #### 二、安装前...

    glassfish-ose-4.0 白皮书

    4. **性能优化**:GlassFish 4.0在性能方面进行了显著优化,包括更高效的线程池管理、内存分配策略以及对JVM的调优,这些都为高并发和大数据量的应用提供了稳定的支持。 5. **云就绪**:作为一款现代应用服务器,...

    glassfish安装步骤.txt

    ### Glassfish安装步骤详解 #### 一、简介 Glassfish是一款开源的应用服务器,它支持Java EE标准,并且在企业级应用开发中具有广泛的应用。为了能够成功安装并配置Glassfish,确保系统环境中已经安装了合适的JDK...

    glassfish api

    《Glassfish API详解与实战指南》 Glassfish API是Oracle公司开发的一款开源的应用服务器平台,其核心在于提供Java EE(Enterprise Edition)应用的运行环境。作为一款强大的服务器,Glassfish API为开发者提供了...

    GlassFish5.0安装包

    每个域代表一个独立的GlassFish实例,可以设置不同的配置参数。默认情况下,安装后会有一个名为`domain1`的域。 3. 部署应用:在Admin Console中,选择“Applications” > “Deploy”,然后浏览并上传你的WAR或EAR...

    glassfish-6_2007

    ### GlassFish概述与关键技术知识点 #### 一、项目GlassFish简介 **Project GlassFish** 是一个开源项目,致力于提供高质量的企业级应用服务器解决方案。它基于Java EE 5规范开发,并作为该规范的参考实现...

    glassfish安装

    - **调整JVM参数**:在`$GLASSFISH_HOME/domain/domain1/config/domain.xml`文件中,可以修改JVM参数以优化性能,如设置堆大小、开启垃圾回收策略等。 - **安全性配置**:在管理控制台中,可以设置用户角色、权限...

    Glassfish部署web项目

    ### Glassfish部署Web项目知识点详解 #### 一、概述 **Glassfish** 是一款开源的Java EE应用服务器,由Oracle公司维护。它基于Java EE标准,支持多种Java EE技术,如EJB、JPA、JSF等。由于其强大的功能和良好的...

Global site tag (gtag.js) - Google Analytics