我一直在从事一个项目,该项目是将数据从一个数据库复制到另一个数据库。用java6编写。并在分布式机器上工作。我们有 9 台服务器。其中一个是主节点,我的主控制模块在该节点上工作,它获取复制请求并将作业分发到其他 8 台机器。
之前就开始用JMS编码来将任务分发到那8台机器上。另一台计算机上有一个Apache Active MQ服务器正在工作。但我发现这不太合适,机器需要更紧密地耦合,因为它会导致一些代码开销,并且有必要为发送到从机的所有消息返回响应消息。我决定改变主节点和其他8台从机之间的互连,并使用RMI进行编码。
我为从机编写了 RMI 服务器,为主节点机编写了客户端。然后在主节点上创建线程来触发从机上的分布式任务。
问题是性能急剧下降。通常情况下,我能够在大约 6 分钟内将大约 6GB 的数据从一个特定数据库复制到另一个特定数据库。现在复制9GB数据需要1个半小时以上。当任务在从机上执行时,它过去会消耗大量的CPU。我观察CPU使用率超过90%。现在它的用量永远不会超过 15%。
我需要的是了解导致性能下降的原因。我应该怎么办 ?我应该使用故障排除工具吗?
编辑------------
好吧,我只在我的笔记本电脑上创建一个从模块实例,并发送 16 个任务来处理它并使用 jvisualvm 分析 CPU。结果如图 CPU Profiler result 所示。 .
当我使用JMS进行机器通信时,包中的控制方法(例如failTaskIfAbort()、performSanityCheck()等)也存在。这让我想到,RMI 线程在某种程度上是低优先级的。
我还上传了从jvisualvm导出的nps文件。您可以在这里获取:exported profile result
最佳答案
对模块进行了一些CPU采样,看起来它在oracle.net.ns.Packet.receive()上花费了大约90%。所以是的,它是关于从数据库获取数据的。这解释了为什么CPU使用率减少了。它等待数据库返回数据。实际上,我很愚蠢,没有在数据库端查看查询性能。我以为我之前复制了这9 GB的数据并得到了很好的结果。该问题与访问分区表有关。与使用 RMI/JMS 进行任务分发无关。
关于java - RMI 性能太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9462882/