代理与非代理消息系统的优缺点

Posted

技术标签:

【中文标题】代理与非代理消息系统的优缺点【英文标题】:Advantages & Disadvantages of Brokered vs non-brokered Messaging Systems 【发布时间】:2017-01-24 13:55:18 【问题描述】:

我正在尝试设计一个模块化的实时监控和控制系统,以便它可以针对不同的硬件和网络进行分布式和扩展/重新配置。

我很快得出结论,我需要某种分布式企业消息传递系统。但是有很多选择,每种都有优点和缺点,其中一些决定了不同的架构。我正在尝试确定我是否需要代理或无代理系统,是否需要某些系统(例如 RabbitMQ)的消息可靠性或 ZeroMQ 等系统的轻量级高吞吐量,或者“按顺序到达” Kafka 的高吞吐量。

首先,这些架构有意义吗?


ZeroMQ 类型“无代理”系统:

注意事项:

每个“B 部分”可以有很多“A 部分”,而“C 部分”可以有很多“B 部分”

优点:

高吞吐量、低延迟 轻松集成到组件中,轻量级部署(无需部署代理)。

缺点

邮件无法保证送达。有些可能会被丢弃。这可能是橙色突出显示区域中的问题。这对 GUI 来说并不重要,但如果本地控制模块正在做出决定,它可能需要所有信息。 (想想看,最新的可能就足够了——用过时的数据做出决定是没有意义的)。类似地,如果 A 和 B 之间的网络出现故障,历史学家将拥有不完整的历史。但这有多重要? 没有“发现”。需要更好地管理组件之间的关系。

RabbitMQ 类型 Broker 系统:

优点:

消息保证送达。 通过代理管理发现。

缺点

慢得多,延迟高 更多的部署和维护(brokers/RabbitMQ 需要安装在机器上,它不只是内置在模块中)

中间选项:

我看过卡夫卡。它是中介的,所以发现会得到照顾。然而,它似乎比 RabbitMQ 更轻量级,虽然它不保证交付(因此更快/更低的延迟),但它确实保持了秩序,而 RabbitMQ 没有。它还可以缓冲消息,以便在出现网络问题时检索它们。

写下来之后,我不确定保证交付的重要性。如果控制模块收到一条消息,如果它是“旧的”,那没关系。如果历史学家有完整的历史,那就太好了 - 但它是必不可少的吗?

在 ZeroMQ 中实现我自己的“消息缓冲区”可能是一个选项,用于在发生故障时存储消息的网络通信。我将拥有比 RabbitMQ 更多的控制权,并且可以在我需要它以通过更不可靠的(通过网络)进行消息传递时实现它。

显然,权衡这些优点或缺点是我的工作。我的问题是:还有什么需要考虑的吗?这两个选项的架构是否有意义?

我计划在 C# 中实现大多数实现,而我目前在消息传递系统方面的经验为零。

【问题讨论】:

【参考方案1】:

实时有保证的消息传递实际上是不可能的。如果系统确实需要实时数据(例如股票交易算法),那么它更关心的是获得具有最低延迟的最新价格,而不是高延迟交付保证。

我认为您应该查看您的系统并将其分解为以下组件:

需要实时(实时控制、决策制定) 需要可靠(历史数据库)

看你的图我觉得你对两个消息系统有很好的要求

zeromq 用于实时控制部分 kafka 用于保证交付历史/数据库部分。

顺便说一句,zmq 发现很容易通过几个冗余 zmq 代理和某种形式的 DNS 解决。

【讨论】:

【参考方案2】:

您建议“在 ZeroMQ 中实现您自己的消息缓冲区以进行网络通信,以便在发生故障时存储消息”似乎是一种可行的方法。你有追求过吗?我会对你这样做的经历感兴趣。

一种具有持久性、低延迟和高吞吐量的“打包”消息管道似乎很理想。在 ZMQ 之上构建它可以大大减少处理开销和管理/设置问题。

【讨论】:

【参考方案3】:

可靠性可能意味着不同的东西。这link from zmq 可能是我读过的最好的之一。但是这里简要解释一下在硬件故障时的可靠性

Apache Kafka - 消息传递保证可能意味着不同的东西。见Message Delivery Semantics。需要注意的是"Kafka's semantics are straight-forward. When publishing a message we have a notion of the message being "committed" to the log. Once a published message is committed it will not be lost as long as one broker that replicates the partition to which this message was written remains "alive". "

RabbitMQ 也提供了一些选项。阅读Clustering and HA。但我个人认为 Apache Kafka 本质上(通过设计)是一个分布式、分区、复制的提交日志服务,因此以更简洁的方式解决了这个问题。

ZMQ 我对 zmq 的了解还不够,无法得出有根据的结论。但我认为 zmq 并没有试图解决可靠性问题。相反,它是一个embeddable networking library,它为高性能、可扩展的集群应用程序提供了一个基础,以便通过消息相互交互。但是,据我所知,它并没有特别解决可靠持久消息的问题(作为代理)。 Apache Kafka 似乎很好地填补了这一领域——它的性能非常好,但提供了实现可靠性的选项。

结论:我认为可靠性不仅仅是经纪人的责任。相反,它是构成您的应用程序的所有部分的共同责任。只有通过良好的设计和使用正确的技术,才能实现可靠性、性能和可扩展性。

【讨论】:

以上是关于代理与非代理消息系统的优缺点的主要内容,如果未能解决你的问题,请参考以下文章

Kafka分布式消息系统剖析

使用 kafka 作为消息代理为桌面/移动/Web 应用程序创建实时推送通知系统

Redis Vs RabbitMQ 作为 Logstash 和 elasticsearch 之间的数据代理/消息传递系统

实习第二天:SIP协议

实习第二天:SIP协议

使用外部消息代理作为代理中继的 Spring