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 通知。
4

11 回答 11

5

好吧,如果您正在寻找基于 Java 的东西,我建议您使用 JMS。它具有您正在寻找的所有功能以及强大的应用程序服务器,例如 JBoss。但是,另一个不完全基于 Java 且不使用队列的选项将使用 HTTP 协议和 JAXB(RESTful Web 服务)。这是双方之间非常轻松的沟通方式。您的对象将通过使用 JAXB 转换为 XML,并传输到另一端,然后在收到它后将其转换回对象。

于 2010-04-08T22:00:33.000 回答
4

老实说,我会坚持使用 JMS。你有一个队列,你的奴隶可以从中取出消息,还有一个队列可以让他们放回消息。您可以在信封上设置有关谁处理每条消息(用于记帐)的属性。您可以通过许多 J2EE 提供程序(glassfish、jboss)获得持久性。

此外,您可以使用它轻松迁移到多服务器分布式 JVM,而无需额外编程。

但是,在某些情况下,它可能不符合“低延迟”的定义。

于 2010-04-07T19:27:23.880 回答
3

还有两个选择:

Zookeeper ( http://hadoop.apache.org/zookeeper/ ) 没用过,不过在这里听上去很合适。RabbitMQ ( http://www.rabbitmq.com/ ) 低延迟消息队列。这里有很大的灵活性。

于 2010-04-07T19:21:54.783 回答
3

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

于 2011-05-27T09:52:05.053 回答
1

你也可以检查骡子。我觉得它是您问题的完美解决方案。

于 2011-05-25T12:12:21.893 回答
0

根据您的要求,您可能会发现 Raw Socket的代码比其他方法少。它肯定会有最低的延迟。您可以通过环回将其缩短到大约 20 微秒。

您的要求越多,您就越有可能需要高级解决方案。但是,如果您想要的只是轻量级的东西,那么原始套接字可能是最简单的。

于 2011-05-30T17:51:03.603 回答
0

我们有一个类似的应用程序,我们只是在 JBoss 上使用 Servlet,而“奴隶”以计时器驱动的方式对其进行处理。这没关系,但对于低延迟来说不是最优的。

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

于 2010-04-07T18:23:50.053 回答
0

您可能想看看 Activatable。如果从服务器在工作完成时响应,那么 rmi 和 Activatable 在这种情况下可能是一个很好的解决方案。如果您在控制器上使用 rmiregistry,那么所有从站都可以轻松地向控制器注册自己,并且可以在需要时激活它们。

于 2010-04-07T18:33:09.627 回答
0

对于 Thrift,您可以使用 TServlet 作为 Thrift 服务的入口点。您所描述的内容听起来更像是一个需要用 activemq 或 zookeeper 解决的问题。

于 2011-10-28T18:55:09.590 回答
0

WebSockets 将帮助您在 Web 服务器和客户端之间进行通信,而不是在两个 JVM 之间。如果这实际上是您想要的, http: //fermiframework.org提供了一个 java 到 JavaScript(服务器到客户端)RMI。

于 2014-03-25T20:18:21.803 回答
0

You can also take a look at Redisson project it has publish/subscribe and other shared distributed data structures for you needs.

于 2016-02-12T14:15:18.533 回答