过去几年我一直在开发一个简约的 Java 富客户端 CRUD 应用程序框架,主要是作为一种爱好,但也积极使用它为我当前的雇主编写应用程序。
该框架通过基于本地 JDBC 的连接或轻量级 RMI 服务器为客户端提供数据库访问。昨晚,我启动了一个负载测试应用程序,它运行 100 个 headless 客户端,用请求轰炸服务器,每个客户端在运行简单用例之间仅等待 1 - 2 秒,包括从简单的电子商店数据库 ( Chinook ) 中选择记录以及相关的详细记录。
今天早上,当我查看服务器分析 session 的遥测结果时,我注意到一些对我来说似乎很奇怪的东西(并让我在当天剩余的时间里保持设置运行),我真的不知道从中得出什么结论。
结果如下:
Memory
GC activity
Threads
CPU load
有趣,对吧?
所以问题是,这是正常的还是不稳定的?这只是 JRE(Windows XP 上的 1.6.0_03)在做它的事情(可能与 JRE 配置有关)还是我的框架设计以某种方式导致了这种情况?
针对 MySQL(而不是嵌入式 H2 数据库)运行服务器不会影响该模式。
我省略了服务器设计的细节,但如果这种行为被认为不稳定,我会很乐意详细说明。
请您参考如下方法:
简短回答:不,我不认为这看起来很可怕。
我认为您没有足够的信息来确定尖峰行为的确切来源。没有任何迹象表明存在内存泄漏、线程泄漏、资源泄漏或明显的争用。也许您的某些任务能够相互协调?无论如何,您似乎观察到了正确的行为,并且个人资料中没有任何内容表明存在危险症状。
也就是说,我强烈建议您升级到最新版本的 Java。 Update 3 太旧了:由于安全问题,我们甚至不允许在工作中使用它。从那时起,垃圾收集器方面也做了很多工作。
作为第一步,我建议升级到最新的 Java(截至撰写本文时为更新 20)并重新运行测试。这种令人费解的行为完全有可能在第二次尝试时消失。
编辑:关于评论中发现的即时死锁,我不会使用该发现来表明多线程编程很难(可行但很难)之外的任何东西。我之前推荐过《Java 并发实践》,并且强烈建议您在编码时将其放在身边。
也就是说,如果可能的话,我还建议避免 RMI。客户端和服务器之间创建的硬连线耦合(客户端挂起,直到服务器满足请求)可能会导致另一层分布式计算复杂性,这对于简单的“请求 + 满足”配对来说确实不值得。
不过,恭喜你找到了僵局。很多时候,我希望自己的(RMI 引起的)问题也能如此简单......