一个好的基于Java的主从通信机制是什么?

20

我正在创建一个Java应用程序,需要在JVM之间进行主从通信,可能驻留在同一台物理机器上。将有一个“主”服务器在Java EE应用服务器(即JBoss)中运行,将连接“从”客户端并动态注册自己以进行通信(也就是说主服务器不知道从服务器的IP地址/端口,因此无法提前配置)。主服务器充当控制器,将工作分配给从服务器,并且从服务器会定期响应通知,因此将进行双向通信。

我最初考虑使用基于RPC的系统,其中每个端点都是服务器,但这可能会变得复杂,因此我更喜欢一种机制,在其中有一个开放的套接字,它们相互交流。

我正在寻找一种通信机制,其低延迟,消息主要是原始类型,因此不需要严肃的序列化。以下是我查看过的内容:

  • RMI
  • JMS:内置于Java中,“从”客户端将连接到应用程序服务器中的现有ConnectionFactory。
  • JAX-WS / RS:主和从均将成为服务器,公开用于双向通信的RPC接口。
  • JGroups / Hazelcast:使用共享的分布式数据结构来促进通信。
  • Memcached / MongoDB:将其用作“队列”以促进通信,尽管客户端必须轮询,因此会有一些延迟。
  • Thrift:这似乎保持着持久连接,但不确定如何将Thrift服务器集成/嵌入到JBoss中
  • WebSocket / Raw Socket:这将起作用,但需要比我想要的更多的自定义代码。

我是否忽略了任何技术?

编辑:还查看了:

  • JMX:使客户端连接到JBoss的JMX服务器并接收JMX通知以进行双向通信。

3
我想你需要在这两个应用程序周围添加一层皮革或PVC,并使用一个安全词协议。 - FrustratedWithFormsDesigner
11个回答

5

如果您正在寻找基于Java的解决方案,我建议使用JMS。它具有您所需的所有功能,还有一个强大的应用服务器,如JBoss。但是,另一种选择是使用HTTP协议和JAXB(RESTful Web服务),它不完全基于Java,并且不使用队列。这是一种非常轻便的双方通信方式。您可以使用JAXB将对象转换为XML,然后传输到另一端,接收时再将其转换回对象。


4

1
Zookeeper看起来非常适合,但我还不确定我是否需要那种级别的功能。我可能需要在周末试用一下。 - Phuong LeCong
只是想感谢你们俩向我介绍Zookeeper。这是一个令人惊叹的分布式计算工具,而Apache curator recipes确实使得使用它变得如此简单。非常感谢! - Fadi Chamieh
只是想感谢你们俩向我介绍了Zookeeper。这是一个令人惊叹的分布式计算工具,而Apache curator recipes真的让它变得非常容易使用。非常感谢你们的推荐。 - undefined

4
说实话,我建议使用JMS。你可以有一个队列让从机从中取出消息,另一个队列让它们将消息放回去。你可以在信封中设置有关每个消息被处理者的属性(用于记账)。许多J2EE提供商(如glassfish和jboss)都提供持久性功能。此外,你可以轻松地将其移植到具有多个服务器分布式JVM的环境中,而无需进行额外的编程。
然而,在某些情况下,它可能不符合“低延迟”的定义。

我认为JMS的低延迟已经足够了。虽然这不是一个实时系统,但我不想使用那些需要使用超过1秒计时器进行轮询的伪队列。这是我的最初想法,但我被所有酷炫的技术所吸引而偏离了原本的方向。 - Phuong LeCong
这是最佳选择。不确定这是否是您的要求,但是使用JMS,每个主节点分配的工作项将保证只会被一个从节点接收。 - sMoZely

3
如果您正在寻求性能,而且两个应用程序都是Java,没有防火墙在中间,那么您可以立即排除所有基于XML的协议。 如果通信是同步的(主控端等待从控端完成作业),则使用RMI,否则使用JMS。 您也可以直接使用TCP以获得最大性能。 如果有许多从节点接收相同的消息,则可以查看诸如JGroups或Spread之类的组通信工具包(更快但不是100%的Java)。 最终,您可能会发现其他人已经构建了您正在尝试构建的内容。看看Gridgain。

1

你也可以检查一下Mule。我觉得它是解决你问题的完美方案。


0

我们有一个类似的应用程序,我们只是在JBoss上使用Servlet,并以定时器驱动方式进行“从属”操作。这还可以,但对于低延迟并不理想。

现在我们正在研究Netty。您可以使用任何您想要使用的协议。我们可能会使用HTTP和JAXB。我想这可以归类为“WebSocket/Raw Socket”,但它比使用原始套接字好得多。


0

你可能想要看一下Activatable。如果从属方在工作完成时响应,那么rmi和Activatable可能是一个不错的解决方案。如果你在控制器上使用rmiregistry,那么所有从属方都可以轻松地向控制器注册自己,并在需要时被激活。


这看起来很有趣。我在Java RMI方面做得不多,所以不知道这个功能。 - Phuong LeCong

0
根据您的需求,您可能会发现原始套接字比其他方法的代码要少。它肯定具有最低的延迟。您可以将其降低到在环回中约20微秒左右。
您的需求越多,您就越可能需要高级解决方案。但是,如果您只需要轻量级的东西,原始套接字可能是最简单的选择。

0

WebSockets 可以帮助你在 Web 服务器和客户端之间进行通信,但不能在两个 JVM 之间进行通信。如果这正是你想要的,http://fermiframework.org 提供了一个 Java 到 JavaScript(服务器到客户端)的 RMI。


0
您也可以查看Redisson项目,它具有适用于您需求的发布/订阅和其他共享分布式数据结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接