系统未扩展以支持并发用户
我在扩展系统上的并发用户数时遇到问题。 根据我的测试,缩放并发用户数似乎直接增加了线性关系中请求的持续时间。
我正在运行部署在具有16Gb RAM的(虚拟)Ubuntu四核机器上的Java Web应用程序。 我正在使用Apache Tomcat 7和MySQl 5.5数据库。 Tomcat和MySQL正在使用默认设置 – 我没有以任何方式配置它们。
我正在使用Apache Benchmark运行一些测试,最终创建一个SQL查询来返回一行数据,其响应大小非常小。
我使用Spring的JDBCTemplate和Apache Commons BasicDataSource。 spring bean的配置如下所示。
com.mysql.jdbc.Driver ${database.username} ${database.password} ${database.url}/${database.schema}
创建几个查询的我的Java方法使用@Transactional注释。
这些是我的测试结果:
- 1请求需要0.2秒。
- 10个请求(同时执行)需要0.9秒。
因此,您可以看到我的应用程序没有缩放。 我不确定问题的原因是什么。 任何人都可以看到我做错了什么或建议我可以进一步调查的方法吗?
提前致谢,
菲尔
更新
更多指标:
1请求,并发1 = 0.22s 10个请求,并发10 = 0.6秒(平均值),0.5(最小值) 100个请求,并发100 = 7(平均值),3.7(最小值) 300个请求,并发300 = 12s(平均值),4.3(min) 300个请求,并发300 = 18s(平均值),6.4(min)
响应大小为1kb。
尝试相同的请求并更改并发性:
300个请求,并发8 =总时间:14.9秒 300个请求,并发20 =总时间:15.3秒 300个请求,并发300 =总时间:24秒
因此,将并发性降低到8可以更快地完成10秒,然后将并发性降低到300.从8减慢交易减少。 8似乎是最佳的并发性。
尝试使应用程序并发时,需要考虑一些事项。
首先,仅仅因为您的服务器有四个核心,并不意味着它们全部可用于您的JVM,您需要询问运行时以查看有多少可用,并且在技术上可以在JVM的生命周期内进行更改,虽然很少见。
接下来,您需要考虑环境的物理拓扑。 数据库是否与应用程序在同一服务器上运行? 如果是这样,您在处理和IO方面会有额外的资源争用,而不仅仅是您的应用程序在做什么。
一旦了解了这些要点,就需要考虑应用程序的IO与处理配置文件。 例如,查找素数并将其输出到系统日志的应用程序实际上是100%处理而0%IO。 在这种类型的应用程序中,没有必要在应用程序中拥有比可用内核更多的线程,因为内核将继续忙于他们正在做的事情,任务切换的开销实际上会降低应用程序的速度。
与数据库密切相关的应用程序通常会对处理配置文件具有相对较高的IO,尽管如果您只是读取该配置文件会降低IO限制,并且这些读取相对较小且具有定义良好的数据库,其中所查询的数据在逻辑上是布局的。 根据整个数据库集是否可以保留在内存中或是否正在进行磁盘分页,数据库的大小也会影响IO。
如果您不熟悉并发性,我强烈建议您阅读Brian Goetz的Java Concurrency in Practice。 话虽这么说,你正在采取一种明智的方法,通过剖析你的应用程序。