使用 ZeroMQ 实现分布式消息系统

“分布式系统是你甚至不知道的一台计算机上的故障可以使您自己的计算机不可用。”-Leslie Lamport

随着云计算的普及和可用性,分布式系统架构已很大程度上取代了更多的整体构建。当然,使用面向服务的架构,言外之意,就是你现在必须面对无数的以前从未存在过的困难,如容错性,可用性和水平缩放。复杂性的另一层有趣的问题是提供一致性的节点,这本身就是一个未完全研究明白的问题。像 PaxosRaft 算法试图提供管理数据复制的方案,而其他解决方案提供最终一致性。

构建可扩展的分布式系统,是一个不小的壮举,但它与构建相似的实时系统比较的话,这算不上什么。分布式体系结构是一个很好理解的问题,事实上,大多数应用对延迟的容忍度很高。有些系统有明显的实时通信的需要,但对于开发者来说这是一个有趣的挑战。在这篇文章中,我探讨用 ZeroMQ 来以可扩展的方式处理分布式实时消息传送,同时也考虑到最终一致性的概念。

智能传输层

ZeroMQ 是一个由C++编写的高性能异步消息库。它不是一个专用的消息 broker,而是一个可嵌入的并发框架,支持通过多种传输的直接和扇出短点。ZeroMQ 实现了许多不同的通讯模式,如通过 TCP 协议请求-应答(request-reply),发布-订阅(pub-sub)和推送-拖拉(push-pull),PGM(多点广播),进程内和进程间的通道。或多或少在设计的时候缺乏UDP协议的支持,因为 ZeroMQ 原本构想能够提供一个原子消息的 guaranteed-ish 传输。这个库没有实际的传输保证,但它却是做出了最大的努力。然而,ZeroMQ 所能确保的是,你不会收到一个部分消息,消息会按照顺序被接收。这个很重要,因为 UDP 协议的性能在损耗和拥挤的环境中才能真正体现出来。

单单就消息传递模式和传输(协议)的综合列表,就让 ZeroMQ 成为构建分布式应用程序的一个有吸引力的选择,但它的特殊优势是其可靠性,可扩展性和高吞吐量。ZeroMQ 和相关技术广泛地应用于高频交易应用中,这些应用一般不允许金融数据包丢失。在2011年,CERN 进行的一项研究,在粒子加速器中比较了 CORBA,Ice, Thrift, ZeroMQ 和其他几个协议,ZeroMQ 排名最高。

cern

在吞吐量上,ZeroMQ 比 TCP sockets 表现更好,因为它使用一些技术:如智能消息批处理,最小化网络堆栈遍历,并禁用 Nagle 算法。默认情况下(尽可能),消息都是排队等待订阅方,并试图避免订阅过慢的问题。然而,当这样做还不能避免的话,ZeroMQ 会采用一种称为“自杀的蜗牛”的模式。 当一个订阅方运行缓慢并且不能赶上进入消息的速度,ZeroMQ 就会说服订阅方来杀死自己。“慢”是由一个可配置的高水位线来决定的。这里的想法是,最好是快速的失败使问题很快得到解决而不是潜在地允许过期的数据流入下游。再次考虑高频交易使用案例。

一个分布式,可伸缩和快速消息架构

ZeroMQ作为一个通讯层使用,它可以成为一个可以信服的案例。让我们探索更深一点,看看它作为一个消息框架在一个实时系统里是如何被使用的。ZeroMQ可以直观地使用并提供了很多语言支持,因此,我们将会更多聚焦在架构上和消息传递的范例上,而不是实际的代码。

大约一年前,当我第一次研究ZeroMQ,我建立了一个框架去演示实时消息并且具备文档同步,它被叫做Zinc。从“文档”,在这层意义上说,任何有良好结构的和为可变数据考虑的文本文档,电子表以及画布(canvas)块等等。从纯学术角度来说,目标是给开发提供一个可建构的丰富框架,应对在分布式环境下的协作体验。

这个框架实际上有两种实现,第一个由原生的 ZeroMQ 所支持,另一个是由纯 Java 实现 JeroMQ 所支持。这专未允许使用任何传输层而设计的。

Zinc 围绕几个核心概念而设计:Endpoints(端点), ChannelListeners(通道监听者), MessageHandlers(消息处理者) 和 Messages(消息)。在应用程序集群中,端点代表一个单一的节点,提供发送消息到其他端点和从其他端点接收消息的功能。它具有分别传输给同类组件和从其他相同组件接收消息的输出和输入通道。

endpoint

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/011e233bc3ee8c48150d3e884829caea.html