【问题标题】:How to design a distributed application using a Message Broker and a Database?如何使用消息代理和数据库设计分布式应用程序?
【发布时间】:2011-02-04 21:13:43
【问题描述】:

我想实现一个分布式销售点系统,有点像Point of sale app architecture advice 中描述的系统。

这是一个具有以下特点的分布式系统:

  • 客户端是关键任务,即使网络连接或服务器出现故障,它们也应该可以工作,但只需要几天左右的时间。
  • 客户端必须易于安装。
  • 每个客户端都有自己的本地嵌入式数据库。
  • 客户端和服务器之间的通信使用消息队列。
  • 服务器用于备份、记账、统计和向客户分发价格。
  • 服务器放置在互联网上。

我正在以 JavaDB 作为数据库在 Java Swing 中实现客户端。

我的应用程序应该如何与消息代理和数据库通信?

我以前从未使用过消息队列和消息代理。我的想法是应用程序从数据库读取,但写入消息代理,消息代理写入数据库并与服务器通信。或者这是一个坏主意?我该如何解决这个问题?

所以除了我的嵌入式数据库之外,我还需要找到一个消息代理,最好是用 Java 编写的可以嵌入到我的应用程序中的消息代理,以便于安装。

【问题讨论】:

  • 我不擅长制定答案。您可能想查看“企业集成模式”(Hohpe、Woolf、Addison-Wesley)。然而,这个要求听起来很可怕:“即使网络连接或服务器出现故障,客户端 [...] 也应该工作,但只是几天左右”和“服务器用于 [...] 分发 [ ing] 给客户的价格。”你能保证价格不会改变吗,即你事先知道价格变化的日期吗?
  • "我的想法是应用程序从数据库中读取,但写入消息代理,消息代理写入数据库并与服务器通信。或者这是一个坏主意?.. ." 这不是一个坏主意,但您至少应该决定您希望使用哪个消息代理。有些可能有预制部件直接与数据库对话,否则你也应该在另一边编写一些代码......
  • @mnemosyn:不,没有价格变化的日期。价格可以改变,你也可以改变客户的价格。但在连接再次建立之前,它们不会分发给其他客户端。
  • @p.marino:我以前没有使用过消息代理,所以我必须找到一个。但我想使用一种独立于语言和平台的。而且我什至不知道我需要一个嵌入式消息代理还是只需要一个消息客户端。 “否则你也应该在另一边编码一些东西”是什么意思?我是否需要在应用程序中使用 Message Queue 客户端来从同样嵌入的消息代理读取消息?

标签: client-server messaging point-of-sale architecture distributed-system


【解决方案1】:

在纯技术层面上,这可能是一个很好的起点:http://java.sun.com/products/jms/tutorial/

您还绝对应该得到一本“企业集成模式”一书,它解释了可以使用排队系统的所有各种方式。

根据您的描述,我认为以下模式很有用(抱歉,不知道书中使用的术语,因为我现在没有。自己编):

  • 发布订阅:服务器将发布消息(例如价格信息的更新),这些消息将传递给订阅此类信息的所有客户端。您必须涵盖的一个重要案例是一个问题,即当您的客户端在此类广播期间断开连接时会发生什么。您必须确保它不会错过任何消息,或者有办法再次赶上。

  • 即发即弃:一个通信伙伴(例如客户端)将发送一条消息,而不会期望任何类型的响应。排队系统将负责最终的交付。这可以用于提交订单等。

  • 回拨:这就像两个或多个相反方向的火灾和遗忘消息。后续调用将有一个 id,以便将消息标记为对之前收到的某个消息的响应。这在您提交订单但需要某种答案时很有用。当然,答案可能会在一天后到达,因此您需要一份未完成订单的列表,该列表可能也应该对用户可见,或者在列表中支持个人。发送多个回复时,必须处理消息乱序到达的情况。如果可能,处理此问题的一个好方法是在每个后​​续消息中包含先前消息的所有信息。这样您就可以简单地丢弃旧消息。

所以沟通可以这样进行: - 服务器偶尔会向所有客户端发送更新。该消息可能应该包含某种版本信息,以便客户端可以确保他们拥有所有消息。 - 定期(或在一段时间内没有收到来自服务器的更新或......)客户端请求来自服务器的特殊更新,以确保它具有所有当前信息。上面提到的版本信息可以用来识别缺失的信息 - 客户端接收消息并将内容存储在本地数据库中 - 客户端从数据库中读取数据以向用户呈现信息 - 客户端向服务器提交订单或其他任何内容,可能会收到不同步的答案

一些一般性建议:

通过排队,您正处于并发地狱的中间。因此,对所有可能“出错”的事情要有创意。例子是 - 消息乱序到达 - 接收者在发送时不可用(这就是首先使用消息传递的原因) - 接收器不可用且永远不会重新上线。消息传递服务器具有保证传递的选项。这意味着他们必须存储消息,直到实际传递它。如果客户端永远不会重新上线,消息将永远保留,填满存储空间

确保所有消息处理都与应用程序的其余部分完全分离,以便于测试。

考虑升级服务器和客户端的过程,尤其是在消息格式发生变化时。您要么必须在同一时间点进行所有升级,中间有一些停机时间,要么您的服务器必须能够在一段时间内处理新旧消息格式。

【讨论】:

  • 感谢您的精彩回答!您对我的方案是应用程序从数据库读取并写入消息代理,代理将其写入数据库并与服务器通信的计划有何看法?
  • 作为一个基本想法听起来很合理。当然,你会发现很多细节问题,但对于每一种应该适用于不可靠网络连接的方法来说都是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 2021-06-10
  • 2011-11-26
相关资源
最近更新 更多