寻找一些想法/模式来解决我将很快开始工作的系统的设计问题。毫无疑问,我需要使用某种消息传递(可能是 MSMQ)在系统的某些区域之间进行通信。我不想重新发明轮子,但同时我想确保我使用正确的工具来完成这项工作。我一直在修改和阅读 NServiceBus,它的功能给我留下了深刻的印象——但我不确定它是否适用于我想要实现的目标。
这是系统需要做什么的(希望)非常简单和概念性的描述:
我有一个客户可以向其发送消息的服务。该服务是“Fire and Forget”——客户得到的最多可能是成功或失败(成功是收到消息)。
每条消息的处理/处理都非常重要,并且可能会占用大量系统资源。因此,只能同时处理 X 条消息,其中 X 是可配置的值(基于系统规范等)。传入的消息将存储在队列中,直到“轮到他们”处理。
对于每个客户端,消息必须按顺序处理(FIFO)。但是,某些客户端可能会连续发送许多消息(数千条或更多),例如,如果它们在一段时间内失去连接。出于这个原因,必须在客户端之间以循环方式处理消息——不允许客户端吃饱,也不允许客户端饿死。因此,系统要么必须能够查询特定客户端的队列,要么为每个客户端创建单独的队列(自动,因为客户端在编译时不为人所知)并轮流从中提取。
我目前的想法是,我真的只需要使用 vanilla MSMQ,创建一个服务来接受消息并将它们写入一个或多个队列,然后创建一个进程来从队列中读取消息并处理/处理它们。但是,使用 NServicebus 之类的东西获得的可靠性、审计、可扩展性和易于配置看起来非常吸引人。
ESB 是不是适合这项工作的工具?还有其他一些我应该研究的技术或模式吗?
更新
一些澄清。
关于“按顺序”处理消息——在单个客户端的上下文中,消息绝对需要按照接收到的顺序进行处理。解释确切的原因很复杂,但这是一个坚定的要求。我没有提到每个客户端只能同时处理一条消息。因此,即使有 10 个工作线程并且只有一个客户端有消息等待处理,一次也只会处理其中一条消息——不必担心竞争条件。
我相信这通常可以通过 vanilla MSMQ 实现——您可以在队列中拥有一个消息列表,并始终先获取最旧的消息。
我还想澄清一个循环排序的用例。在此示例中,我有两个发送消息的客户端(A 和 B),并且只有一个工作线程。所有队列都是空的。客户端 A 一夜之间失去了连接,因此在上午 8 点向服务发送了 1000 条消息。这些消息排队,工作线程获取最旧的消息并开始处理它。在处理第一条消息时,客户端 B 将消息发送到服务中,该服务排队(如前所述,可能在单独的队列中)。当客户端 A 的第一条消息完成处理后,逻辑应该检查客户端 B 是否有消息(它是客户端 B 的“轮到”),既然找到了,就下一步处理它。
如果客户端 B 在此期间没有发送消息,则工作人员将继续一次处理客户端 A 的消息,始终在处理后检查其他客户端队列是否包含等待消息,以确保没有客户端被饿死。
我仍然觉得 ESB 之间可能存在不匹配,这个问题是 ESB 旨在促进服务之间的通信;我想要实现的是消息/通信和选择性排队系统的组合。