【发布时间】:2012-01-09 23:49:55
【问题描述】:
我有一个最初在 Axis 1 中设计的 Java SOAP Web 服务,它不符合我的性能要求。
我最关心的请求是用于向数据库添加大量(数百万行)数据的请求。在客户端,我只是循环文件,将这些数据推送到我的 Web 服务。每行包含三个元素,因此请求类似于:
<SOAP Envelope/Header/Body>
<AddData>
<Data>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<Age>42</Age>
</Data>
</AddData>
</SOAP Envelope/Body>
我发现以下性能趋势:
- 当我每个请求执行一行时,我每分钟可以获得大约 720 行。
- 当我将多行封装到一个请求中时,我每分钟最多可以获得 2,400 行(每个请求 100 行)。
不幸的是,该性能无法满足我们的要求,因为我们有数亿行要插入(以每分钟 2,500 行的速度,加载所有数据大约需要 2 个月)。
所以我一直在研究应用程序,看看我们的瓶颈在哪里。每个 100 行的请求大约需要 2.5 秒(我尝试了几个不同的服务器并得到了相似的结果)。我发现了以下内容:
- 客户端开销可以忽略不计(通过监控我自己的客户端的性能和使用 SOAP UI)
- 数据库活动只占总时间的 10% (.2s) 左右,因此 Hibernate 缓存等不会有太大帮助。
- 网络开销可以忽略不计(从客户端到服务器的 ping 时间 10MB/s 的吞吐量)。
所以这留下了大约 2 秒的时间。我可以指出的这个难题的唯一另一部分是在服务器端反序列化传入请求的开销。我注意到 Axis 2 声称在这方面提高了速度,因此我将此功能移植到 Axis 2 Web 服务上,但没有得到我想要的加速(每个请求的总时间提高了大约 10%)。
我是否低估了反序列化上述 100 个元素所需的时间?我无法想象反序列化可能需要大约 2 秒。
我可以做些什么来优化这个 Web 应用程序的性能并减少 2 秒的开销?
提前致谢!
========= 第二天.... =========== 剧情变厚了……
在@millhouse 的推荐下,我对生产服务器的单行请求进行了更多调查。我发现它们可以在良好的硬件上运行得相当快。因此,我尝试使用从 1(1,000 个单独请求)到 1,000(单个请求)的增量添加 1,000 行。
- 1 行/请求 - 14.5 秒
- 3/req - 5.8s
- 5/req - 4.5s
- 6/req - 4.2s
- 7/req - 287s
- 25/req - 83s
- 100/req - 22.4s
- 1000/req - 4.4s
如您所见,额外的 2 秒延迟会在每个请求中产生 7 行(与每个请求 6 行相比,每个请求大约额外增加 2 秒)。我可以始终如一地重现这一点。更大数量的请求都有类似的开销,但是当每个请求插入 1,000 行时,这种开销就变得不那么明显了。数据库时间呈线性增长,与整体请求时间相比仍然可以忽略不计。
所以我发现使用每个请求 6 行或每个请求数千行可以获得最佳性能。
有什么理由为什么 7 的性能会低于每个请求 6 行的性能?这台机器有 8 个核心,我们在会话池中有 10 个连接(即我不知道 6 的阈值是从哪里来的)。
【问题讨论】:
标签: java web-services axis2