【问题标题】:Two way RMI with Spring backed by a message queue由消息队列支持的带有 Spring 的两种方式 RMI
【发布时间】:2019-08-15 20:34:24
【问题描述】:

系统由 1 个或多个客户端和单个服务器组成。每个客户端都是手动添加的,并提供一个标识符 (client.id)。每个客户端都可以向服务器发送消息。服务器可以向每个客户端发送消息。所有消息都可以分为两组:有答案和没有答案。

例如一些签名:

  • CompletableFuture<Response> call(Request requestToServer)
  • void execute(Data dataToSend)

其中 Response、Request 和 Data 是我的 POJO。

所以,我需要某种 RMI 来实现服务器和客户端之间的消息通信。

要求:

  1. 服务器在处理消息时必须能够通过其 id client.id 识别客户端,但客户端在发送该消息之前不应直接填写此标识符;
  2. 消息应该是 POJO;
  3. 能够回答异常消息;
  4. 事件驱动的处理程序(如@RabbitListener) - 多个处理程序 - 每个传入消息类型的spring bean,有或没有返回类型。应根据传入的消息类型自动解析处理程序;
  5. 由 RabbitMQ 或 ArtemisMQ 支持;
  6. 从服务器向客户端发送消息的单一服务:发送消息时应提供客户端 ID。示例:void sendToClient(int clientId, Data dataToClient)

我尝试设置这种沟通方式的方法:

  1. Spring 集成 我自己的网关与完整的未来 - 太棒了。此外,可以使用client.id 丰富邮件标题 - 很棒。但是我没有找到合适的方法来处理传入的消息并能够回答它。试图发布一个 ApplicationEvent,但所有事件处理程序都有一个 void 返回类型。所以,我的想法是获取相关 ID 并发送回消息,提供该相关 ID - 这看起来不是一个明确的解决方案。

  2. RabbitListener/RabbitTemplate 缺点:

    • 设置 RabbitTemplate 以发送和接收消息的大量代码;
    • 需要手动设置请求和回复队列和绑定;
    • 在@RabbitHandler 中解析client.id 时出现问题。
  3. AmqpProxyFactoryBean 最接近我需要的结果,但有几个我无法解决的问题:

    • 在消息处理程序上解析client.id
    • 每个服务接口方法有一个处理程序。

因此,我需要一个轻量级的解决方案来建立服务之间的通信,并由消息队列提供支持。添加其他消息类型应该很容易 - 声明类,将处理程序添加到消费者并创建该类的对象并从生产者发送。

但也许我完全错了,关于服务通信?也许我不应该为此使用消息队列?

【问题讨论】:

  • 这一切都很混乱。 要么你想要RMI或者你想要消息队列。它们是完全不同的编程范式。 JMS 有一个监听器风格的 API。 RMI 有一个方法调用风格的 API。你需要下定决心,这是你想要的。你不能两者兼得。
  • 谢谢,我想,如果我在这种情况下将术语 RMI 更改为 RPC,它会更接近我的问题。

标签: java spring message-queue rmi mq


【解决方案1】:

使用像 RabbitMQ 这样的消息队列或消息代理是一个非常有效的解决方案。但是你必须考虑它是否是你真正需要的。

消息代理允许您分离消息的生产者和消费者。它还允许您引入一定程度的容错。如果消费者暂时不可用,则消息不会丢失。但是,这也意味着,如果期望得到回复,则消息的生产者可能会错误地认为另一端已处理其请求并继续等待回复。消息代理还经常提供某种保证,例如一次且仅一次或至少一次,以及如何处理无法传递的消息(例如死信队列)、生存时间和各种路由的策略能力(如一致的基于哈希的路由)。在您的情况下,如果您的服务器发起的消息仅到达一个客户端,您可能必须通过一些带有 client.id 的标头值进行路由。

如果您不关心这些功能中的任何一个,而只是想要一种通信结构,那么也许选择一些不同的东西可能更有意义。例如 Akka 提供actor-based distributed communication

如果困扰您的只是解决方案的清洁度或样板的数量,那么查看其他实现可能会有所帮助。你可能想看看Reactive Streams API implementation for RabbitMQ,应该更抽象一点。

【讨论】:

  • 谢谢,这对我来说很有意义。 Akka 是一个非常有趣的解决方案,但我不想在项目中使用任何反应性 - 我对此没有足够的了解。但现在我正在研究 gRPC 作为我的问题的解决方案。
  • 好吧,普通的 Akka 与反应性无关。紧随其后的是 Akka 之上的反应式流实现。 Akka 只是一个基于 actor 的框架,用于发送消息并让工作人员使用它们。很像 rabbitmq 为它实现了一个响应式流抽象。 gRPC 也很酷而且性能很好。但它不是这样的消息代理。
猜你喜欢
  • 1970-01-01
  • 2012-03-25
  • 2018-07-27
  • 2021-09-12
  • 2023-04-05
  • 2021-06-17
  • 2021-12-23
  • 2018-06-30
  • 1970-01-01
相关资源
最近更新 更多