我正在Ubuntu 14.04LTS服务器上运行带有Spring REST服务的Tomcat 7.0.55实例。我正在和Gatling一起进行性能测试。我使用访问REST后端的前端应用程序创建了一个模拟。
我的配置是:
Total RAM: 512MB, 1 CPU, JVM options: -Xms128m -Xmx312m -XX:PermSize=64m -XX:MaxPermSize=128m
环境可能看起来效率不高,但如果我没有超过~700用户的限制(我在7分钟内处理90k请求),我会很快成功处理所有请求。
当同时存在太多连接时,我开始遇到问题。失败的情况是在7分钟内有大约120k的请求。当有大约800个并发用户在玩时,问题开始出现。在用户数量为600-700之前,一切正常,但在此限制之后,我开始获得例外:
java.util.concurrent.TimeoutException: Request timed out to /xxx.xxx.xxx.xxx:8080 of 60000 ms
at com.ning.http.client.providers.netty.timeout.TimeoutTimerTask.expire(TimeoutTimerTask.java:43) [async-http-client-1.8.12.jar:na]
at com.ning.http.client.providers.netty.timeout.RequestTimeoutTimerTask.run(RequestTimeoutTimerTask.java:43) [async-http-client-1.8.12.jar:na]
at org.jboss.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:556) [netty-3.9.2.Final.jar:na]
at org.jboss.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:632) [netty-3.9.2.Final.jar:na]
at org.jboss.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:369) [netty-3.9.2.Final.jar:na]
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) [netty-3.9.2.Final.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_55]
12:00:50.809 [WARN ] c.e.e.g.h.a.GatlingAsyncHandlerActor - Request 'request_47'
failed : GatlingAsyncHandlerActor timed out
我认为这可能与小jvm有关。但是,当我将环境升级到:
Total RAM: 2GB, 2CPUs, JVM options: -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m
我仍然得到非常相似的结果。失败请求的差异无关紧要..
我一直在玩设置Tomcat连接器没有任何效果。当前的tomcat设置为:
<Connector enableLookups="false" maxThreads="400" maxSpareThreads="200" minSpareThreads="60" maxConnections="8092" port="8080" protocol="org.apache.coyote.http11.Http11Protocol" connectionTimeout="20000" keepAliveTimeout="10000" redirectPort="8443" />
操作线程数,连接数,keepAliveTimeout根本没有帮助让800个并发用户无需超时。我计划扩展应用程序以处理至少2k并发用户,但到目前为止,我可以看到垂直扩展和升级env没有给我任何结果。我也没有通过jvisualvm看到任何内存问题。操作系统不应该是限制,ulimits设置为无限或高值。数据库不是瓶颈,因为所有REST都使用内部缓存。
在我的情况下,tomcat似乎无法处理超过800个连接用户。您对如何解决这些问题有任何想法吗?我希望能够扩展到至少2k用户,并尽可能降低失败率。我会很感激我能如何解决这些问题和提示。如果您需要更多详细信息,请发表评论。
干杯 亚当
答案 0 :(得分:0)
您是否增加了打开的文件编号。每个连接都使用一个打开的文件项。
答案 1 :(得分:0)
鉴于您在如此短的时间内创建了如此多的连接,您可能会达到TCP连接的限制。默认情况下,Linux在清理连接之前会等待一段时间。测试失败后,运行netstat -ant | grep WAIT | wc -l
并查看您是否接近60,000。如果是,则表示您可以对TCP堆栈进行一些调整。尝试更改以下sysctl
设置:
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_fin_timeout = 5
您还可以尝试this ServerFault question中提到的其他一些设置。