delphi zeromq开源库

delphi zeromq开源库

https://github.com/grijjy/DelphiZeroMQ

使用 ZeroMQ 推出您自己的轻量级、可扩展后端
ZeroMQ是一种高速分布式消息传递库,用于使用 pub-sub、push-pull 和 router-dealer 等智能模式构建可扩展的通信应用程序。在本文中,我们将展示一个 Delphi 版本的ZeroMQ Majordomo 协议规范,它是一个轻量级的分布式通信框架,用于创建在 Windows 和 Linux(使用 Tokyo 10.2)上运行的服务守护进程以及在 Windows、Linux、iOS 和 Android 上运行的客户端应用程序。我们还将演示用于 ZeroMQ 的 CZMQ 高级绑定的 Delphi 版本,我们称之为 PascalZMQ。

ZeroMQ 和 Majordomo 协议非常适合现有的基于云的分布式模型,这些模型在云服务(如 Google Compute 和 Amazon 的 Web 服务)上运行。它非常适合带宽有限、连接并不总是可靠且您的后端服务需要动态扩展的移动应用程序和物联网应用程序。

ZeroMQ 的 Majordomo 协议使用工作模块网络来执行各种服务和有效路由活动的代理。客户端还使用 ZeroMQ 协议与 Broker 互连并发送消息。ZeroMQ 的 Majordomo 协议中的通信在所有端点之间双向流动。这允许您创建一个分布式 BAAS,其中请求可以与即时响应或产生稍后到达的结果的操作相关联。

Delphi 还有一些其他的 ZeroMQ 实现。然而,据我们所知,还没有对 Delphi 中的 Majordomo 协议进行详尽的介绍,也没有对 CZMQ 库的完整翻译,我们也将在本文中讨论。这些将是我们讨论和实施的主要主题领域。

IP套接字的替代品
在最基本的层面上,ZeroMQ 提供了一种跨平台传输,您可以使用它来代替 TCP 套接字或 HTTP 请求/响应。它是为提高效率而构建的,它没有 http、socket.io 或 WebSockets 的开销。对于带宽有限的情况(例如移动应用程序或物联网应用程序),它是一个绝佳的选择,并且性能至关重要。

它管理创建和管理连接和断开连接以及通过不可靠连接对数据进行排队的所有复杂性。它负责在内部节点之间路由数据,因此通信是双向的,并且专注于保持有效负载开销的效率。

您可以创建使用可扩展通信模型(例如 Linux 上的 EPOLL 或 KQueue)的服务器,并且您的通信模式可以通过 TCP、进程间、线程间等等。ZeroMQ 的美妙之处在于这些复杂性是抽象的,您可以随时更改传输模型和操作系统平台,而无需更改代码中的逻辑。

使用 ZeroMQ,您可以编写一次通信代码,然后在 Delphi 可以针对的任何地方运行,例如 Android、iOS、Windows 和 Linux。

PUB/SUB、经销商/路由器、推/拉等
然而,将 ZeroMQ 描述为套接字通信的替代品确实是不公平的。ZeroMQ 能够支持许多不同的数据路由模型,包括发布者/订阅者、推/拉和经销商/路由器。使用这些模型,可以构建许多不同的通信解决方案。

可以创建许多不同的解决方案,我们不可能一一描述它们。许多接口在我们的 ZeroMQ 类中实现,但详细讨论它们远远超出了本文的范围。有关这些主题的完整讨论,请参阅ZeroMQ 网站上的优秀文档。

主管协议
ZeroMQ 提供了一种分布式消息模型,他们称之为Majordomo 协议。在 Grijjy,我们完全在 Delphi 中实现了 ZeroMQ Majordomo 协议,因此我们可以构建大规模的 Worker 和服务后端。

Majordomo 协议有几个通常在不同节点上运行的组件。客户端通常在桌面操作系统或移动设备(Windows、Linux、iOS 或 Android)上运行。Broker 位于云中的一个或多个节点上,负责处理路由和负载平衡。Worker 是一个处理一个或多个服务的节点。在 Majordomo 模型中,您不仅可以拥有几乎无限数量的经纪人,还可以拥有执行各种服务的工人。

该模型被设计为无状态的,因此任何经纪人或工人都可以代表任何客户处理工作。ZeroMQ 在内部处理 Worker、Broker 和客户端之间的路由,因此您可以建立适合您的实施的通信模式。例如,您不限于单个请求的单个响应。使用 ZeroMQ 可以随时随地进行任意通信。

帕斯卡ZMQ
ZeroMQ 的基础库非常低级,因此为了提供消息和帧传输,他们创建了CZMQ 库。这个库是围绕低级基础 ZeroMQ API 的更高级别实现,旨在允许您将自己的数据包含在用于数据封装的 ZeroMQ 多部分消息中。

在 Grijjy,我们使用这种消息传递和框架模型,但出于性能和内存管理的考虑,我们开发了自己的转换,我们称之为PascalZMQ。它是否与 C 版本本质上相同,但包装在易于使用的 Delphi 对象模型中并增强了效率和性能。

在这个实现中,我们添加了Google Protocol Buffers的实现。当您的带宽有限时,Google Protocol Buffers 是一个很好的选择。我们的实现允许您将任何给定的 Delphi 记录序列化为提供给 ZeroMQ 传输的二进制对象。这种方法使得 Delphi 相关类型以跨平台的方式移动既简单又高效。有关此主题的更多信息,请参阅下面的 Google 协议缓冲区部分。

构建 ZeroMQ
为了使用 ZeroMQ,您需要为每个平台提供一个库。此外,您需要构建另一个名为libSodium的库,用于加密。虽然您不必使用 libSodium 和 ZeroMQ 加密,但如果您选择添加它,我们仍将讨论该过程。

对于我们的示例,我们为您预先构建了适用于 Windows、iOS 和 Android 的库二进制文件。如果您想自己构建它们,您需要从http://zeromq.org/和http://libsodium.org下载最新的源代码。对于 libSodium,源文件位于https://download.libsodium.org/libsodium/releases/

Windows 需要 libzmq.dll。在我们预先构建的二进制文件中,libSodium 被包含并链接到最终确定的 libzmq.dll 中。

Linux 需要 Linux 开发服务器(运行 PAServer 的地方)上的 libzmq.so 和 libsodium.so。您使用典型模式构建 libsodium,
。。。。。。。。。
Majordomo 协议中的 Broker 将一组给定的客户端连接到单个 Broker 和一个 Worker 池。客户端连接到 Broker,Worker 也是如此。正如 RFC 中最好的描述,

“客户端和工作人员互不相见,都可以任意来去。代理可以打开两个套接字(端口),一个前端给客户端,一个后端给工作人员。但是 MDP(Majordomo 协议)是还设计为在单个代理套接字上工作。

我们将“客户端”应用程序定义为发出请求的应用程序,将“工作”应用程序定义为处理它们的应用程序。”

“Majordomo 代理处理一组共享请求队列,每个服务一个。每个队列有多个写入者(客户端)和多个读取者(工作者)。代理应该公平地为客户服务,并且可以在任何基础上向工作者传递请求,包括循环和最近最少使用的。”

Broker 的作用是将您的请求快速路由到代表您的客户执行服务的 Worker 上,同时也可以轻松地处理因各种原因来来往往的 Worker 的网络问题。

最小的 Broker 示例只需要 2 种方法,一种用于处理来自 Clients 的消息的方法,一种用于来自 Workers 的消息的方法。
。。。。。。。。
TZMQAction.Forward,它告诉 ZeroMQ 堆栈简单地将消息路由到预期的目标。然而,我们可以在这里做出许多其他决定,包括将消息的目标目的地更改为另一个客户端或工作人员。我们也可以完全丢弃该消息。如果需要,我们还可以检查消息的内容。

通常,Broker 会快速处理和转发消息,因此它应该只检查与关键信息相关的消息。例如,如果您正在构建一个完全无状态的模型,您将需要某种形式的令牌身份验证。您可以创建一个 Authentication Worker 服务来验证用户的凭据,当 Broker 从 Authentication 服务接收到批准用户的消息时,它会反过来创建一个 Auth 令牌。然后,此令牌将包含在客户端消息的有效负载中,并在转发或丢弃给定消息之前由 Broker 验证。
。。。。。。。。。
Majordomo 协议中的 Worker 根据您的要求处理服务活动。您可以拥有完全不同的工人来处理不同类型的工作(即:不同的服务名称)和几乎无限量的任何给定服务。这允许您根据应用程序需求动态扩展或收缩后端云。

如果您需要更多身份验证,则只需启动另一个身份验证工作程序。Majordomo 协议中的 Broker 负责负载平衡请求并自动处理路由回各自的客户端。

ZeroMQ 消息是构建为堆栈的多部分消息。在这种情况下,我们将从消息中“弹出”我们的字节,对其进行分析并发送回响应。

ZeroMQ Majordomo 协议中的 Client 只是一个接口协议类和通信的支持单元。
向 Broker 发送消息,Broker 又转发给我们想要的 Worker,将二进制有效负载发送AData到名为 的服务AService。

ZeroMQ 使用类似于堆栈的多部分消息模型。它支持使用基本的 Delphi 数据类型以及二进制对象构建多部分消息。它相对高效,但并不像我们想要的那样紧凑。它也不太适合 Delphi 复杂类型和记录的数据序列化。

在我们的 PascalZMQ 单元和类中,我们实现了以下 ZeroMQ 推送/弹出行为,

TZMessage.PushInteger
TZMessage.PushSingle
TZMessage.PushDouble
TZMessage.PushEnum
TZMessage.PushString
TZMessage.PushBytes

TZMessage.PopInteger
TZMessage.PopSingle
TZMessage.PopDouble
TZMessage.PopEnum
TZMessage.PopString
TZMessage.PopBytes
此外,我们添加了各种 Peek() 方法,例如:

TZMessage.PeekInteger
TZMessage.PeekSingle
TZMessage.PeekDouble
TZMessage.PeekEnum
TZMessage.PeekString
TZMessage.PeekBytes
但是在内部,我们更喜欢 Google Protocol Buffers 的简单性和效率。Google Protocol Buffers 提供了一种高效的数据压缩模型,非常适合物联网和移动应用程序。由于这些限制,我们扩展了基本 PascalZMQ 类以支持我们的 Google Protocol Buffers 实现。

使用我们的 Google 协议缓冲区的 Grijjy 实现,您可以直接将 Delphi 记录序列化为二进制对象,这些对象可以从 ZeroMQ 的堆栈中推送和弹出。

为了支持这个特性,我们添加了额外的特定于协议缓冲区的 push 和 pop 方法,

TZMessage.PushProtocolBuffer
TZMessage.PopProtocolBuffer
TZMessage.PeekProtocolBuffer
默认示例我们不启用 LibSodium 中的加密功能。但是,启用 ZeroMQ 支持的加密相对简单。

要启用加密,您需要首先更改Bind()Broker 的参数,如下所示,

Broker.Bind( ' tcp://*:1234 ' , TZSocketType.Router, True);
这将导致代理在重新启动时创建证书。Connect()然后,当您从 Worker 和 Client调用时,您必须使用 Broker 的公钥(包含在证书文件中) 。

ZeroMQ 安全模型中还有其他受支持的模型,例如为客户端创建的服务器端证书等。这些其他方法提供了对安全模型的更大控制。
你能用这个做什么?好吧,这种可能性令人难以置信。在内部,我们构建了一个无状态的 BAAS 模型,可以在 Google Compute Engine 中动态扩展和收缩。

我们还使用它创建了一个 Delphi 跨平台远程云记录器,因此您可以从任何平台(包括 iOS、Android 和 Linux)发起调试风格的消息,并在您的 Windows 工作站上近乎实时地接收这些消息。我们将在下一篇文章中演示这个示例。
ZeroMQ 及其 Majordomo 协议的美妙之处在于,您可以快速构建高效执行且高度可扩展的服务,这些服务完美适合云计算部署。ZeroMQ 承担了为您的项目管理容错和负载平衡的大部分复杂性。它非常适合物联网项目甚至更大的 BAAS 项目。

我们希望您会发现此实现对您的跨平台项目很有用。

还需要GrijjyFoundation开源库配合才能编译。

https://github.com/grijjy/GrijjyFoundation

编译后运行效果图(集群负载均衡):

 

posted @ 2021-01-05 09:58  delphi中间件  阅读(795)  评论(0编辑  收藏  举报