如果我正在使用消息队列构建一个包含数十个发布者/订阅者的系统,那么我似乎有一些网络配置选项:
- 我可以拥有一个所有机器都使用的集群代理——每台机器都没有本地队列
- 我可以在每台机器上本地安装代理,并使用存储转发将消息传递到远程机器
不同的技术似乎强制执行不同的配置——例如,MSMQ 要求每台机器都有自己的本地队列,而 Tibco EMS 似乎经常在集群中使用,每个消费者都没有本地队列。
没有本地队列有什么缺点,哪些因素会影响决定?
如果我正在使用消息队列构建一个包含数十个发布者/订阅者的系统,那么我似乎有一些网络配置选项:
不同的技术似乎强制执行不同的配置——例如,MSMQ 要求每台机器都有自己的本地队列,而 Tibco EMS 似乎经常在集群中使用,每个消费者都没有本地队列。
没有本地队列有什么缺点,哪些因素会影响决定?
没有提供持久消息存储的本地队列意味着您无法保证消息传递。在具有本地代理实例的集群中使用 RabbitMQ 之类的东西为您提供了一种持久的机制来存储消息以进行传递。如果您必须通过网络连接到远程代理以发送持久消息,则您面临更高的网络故障风险。
MSMQ 也是存储转发的,但它不提供任何集群路由功能。这意味着应用程序必须完成这项工作(或在其之上有一个层,例如 MassTransit 或 NServiceBus 为您完成)。
当我想到 TIBCO 时,我想到了一个集中的 EMS 服务器集群,应用程序服务器与之通信,而不是在本地运行代理实例。围绕 EMS 和 BusinessWorks 应用程序服务器的 GUI 工具确实在那个世界中强制建立了一个模型。
在任何将消息存储在本地的分布式情况下,重要的是确保机器本身配备了适当的消息存储设备,具有快速磁盘和足够的磁盘来满足预期的消息积压/容量。
在大多数情况下,我会冒险使用本地队列。
如果消息需要持久,则本地队列是必需的。换句话说,如果与远程队列的连接不可靠,并且您希望消息最终到达其订阅者,您将需要本地队列的存储和转发功能。
如果消息不需要是持久的(在事件触发后可能会丢失),那么远程共享队列将是一个选项。
您可能想查看NServiceBus 分发器模型,这将是您的两种方案的混合体:每台机器上的本地队列转发到远程代理/分发器集群。
我不确定我是否同意 MSMQ 上的评论,因为它们似乎已经过时了。也许我错过了一些东西。
MSMQ 支持这两种方案。
在场景 1 中,客户端将使用事务性远程接收(MSMQ 4.0 及更高版本)。作为事务性,接收是可靠的并且消息是持久的(与早期版本的 MSMQ 不同,因为中止接收将消息留在服务器上)。
在场景 2 中,存储转发传出队列将发送到客户端上的本地事务队列(同样可靠且持久)。
可靠性和持久性不应该是使用本地队列还是远程队列的决策点。性能是 MSMQ 的差异化因素。