向客户端广播消息

Broadcasting message to clients

设计

服务器代理不断轮询数据库 (SQL Server 2012) 以查找客户端代理所需的计划 and/or 配置是否有任何更改。客户端代理在网络上的所有机器上运行,需要从服务器代理获取更新的扫描计划和配置,并更新其作业调度程序。服务器代理和客户端代理都内置于Java.

问题陈述

数据库更新后,服务器将数据发送给 n 个客户端代理。

解决方案1

在服务器和客户端代理上创建网络服务并相互使用。每当数据库中的扫描 schedule/configuration 发生变化时,服务器将调用客户端代理的方法并更新配置文件。

缺点解决方案1

在可运行的 JAR 中,在所有客户端代理上部署 Axis2/Jetty/Similar webserver。考虑到这是在所有客户端代理上部署网络服务器,其中数量可能高达 150000,是否可取?另外,如果所有客户端机器上都有网络服务器,应用程序是否可以通过安全认证?

解决方案2

使用RMI 在服务器和客户端之间进行通信。在这种情况下,客户端将保持轮询服务器,因为 RMI 通信是单向的。应避免使用双向调用,因为它再次涉及在每台客户端计算机上都有服务器套接字。

缺点解决方案2

每当更新数据库时,它都无法直接向所有客户端机器发送消息。它必须等待客户端机器轮询它。如果需要立即扫描,所有客户端代理都需要频繁轮询主代理。考虑到客户端代理的数量可能很大,这是否可取? Java 架构师告知的另一个缺点是 RMI 比 webservice 慢。对吗?

我必须选择这两种解决方案之一,或者如果有任何第三种解决方案你们可以给我。还有人推荐JMS作为广播方式

您的解决方案 1 还有另一个问题 - 每个人都知道服务器,但服务器不会知道所有的客户端。当然,您可以在服务器上执行客户端注册工作流程,但是发布消息会使服务器变得很重

我什至不考虑这里的解决方案 2。 RMI 对我来说就像死了一样好,我们现在有更好的架构。

  1. 在订阅模型中调出消息队列。每当有更新将消息推送到队列管理器时,让队列管理器负责向所有可用客户端广播。您可以在这里使用任何可靠的队列,例如 RabbitMQ、MQTT 等。

主要优势是消息传递的可靠性。有一些选项可以确保每个订阅者都能收到消息,这很好。如果需要,您可以稍后再做一个 push/pull。您还可以集群消息队列,如果客户端数量增加,稍后将创建负载平衡解决方案。

  1. 如果对传输速度有要求,也可以使用websocket。但这不如选项 1,因为它的资源占用。但如果您不担心,websockets 是一种超酷的全双工通信方式。