为什么要使用AMQP / ZeroMQ / RabbitMQ


73

而不是编写自己的库。

我们正在这里的一个项目中进行工作,该项目将是一个自划分服务器池,如果一个部分变得太重,经理将对其进行划分并将其作为单独的进程放在另一台计算机上。它还会警告所有连接的客户端,这会影响连接到新服务器。

我很好奇将ZeroMQ用于服务器间和进程间通信。我的伴侣更愿意自己动手​​。我希望社区能够回答这个问题。

我本人是一个相当新手的程序员,刚刚了解了消息传递队列。当我搜索和阅读时,似乎每个人都在使用消息队列来处理各种事情,但是为什么呢?是什么使它们比编写您自己的库更好?为什么它们如此普遍,为什么那么多?


4
您不应该编写自己的库的原因是,按照您自己的说法,您是“一个相当新手的程序员”。您为什么要使用由新手程序员编写的MQ库?
杰夫·哈蒙德

Answers:


77

是什么使它们比编写您自己的库更好?

推出应用程序的第一个版本时,可能什么都不做:您的需求已得到很好的定义,并且您将开发一个满足您需求的消息传递系统:小的功能列表,小的源代码等。

当您实际上必须扩展应用程序并向其添加更多功能时,这些工具第一个发行版之后非常有用。让我给你一些用例:

  • 您的应用程序必须与一台小端计算机(x86,intel / amd)与一台大端计算机(sparc / powerpc)进行通信。您的消息传递系统具有一些字节序排序假设:请对其进行修复
  • 您设计了自己的应用程序,因此它不是二进制协议/消息系统,但现在它非常慢,因为您花费了大部分时间对其进行解析(消息数量增加,并且解析成为瓶颈):对其进行调整,使其可以传输二进制/固定编码
  • 最初,您在一个局域网内有3台计算机,没有任何明显的延迟,所有东西都到达了每台计算机。您的客户端/老板/ pointed-hair-devil-boss出现并告诉您,您将在不受管理的WAN上安装该应用程序-然后开始出现连接失败,延迟时间长等情况。您需要存储消息并重试发送稍后:返回代码,并将其插入(并享受)

  • 发送的消息需要答复,但不是全部答复:您向其中发送一些参数,并期望得到电子表格,而不仅仅是发送并确认,然后返回代码并将其插入(并享受)。

  • 一些消息很重要,接收/发送需要适当的备份/持久性/。你为什么问 ?审计目的

还有我忘记的许多其他用例...

您可以自己实现它,而不必花费很多时间:反正以后您可能会替换它。


嗯,非常感谢。这无疑给了我一些思考。
Evil Spork,2009年

根据官方zeromq指南,zeromq不提供持久性。该指南向您展示了如何执行此操作,但是我宁愿将持久性融入框架中,而不使用一些未经测试的教程代码!
罗宾·格林

3
对于“在发布应用程序的第一个版本时,可能什么都不是”,您表示不同意。您最后说到,无论如何,第一个版本都将被库重写,还可以从您最终不会丢弃的内容开始。否则,我同意。
2012年

@OO通常在大多数情况下所需的初始功能很小,并且您不能始终证明导入第三者的东西的正当性:需要批准,对代码进行安全性筛选等,具体取决于您为谁工作,这比开发时间要多得多。因此,您从小处着手,使用公司中已经存在的工具自己进行操作,然后当您的代码在产品中被大量使用时,使用第三方工具变得更加容易。您的里程可能会有所不同,但通常公司不希望使用庞大的第三方资源/框架/库。
ppi 2013年

40

这非常像询问:为什么可以在编写自己的数据库时使用数据库?

答案是,使用已经存在了一段时间并且在许多不同用例中都广为人知的工具,随着时间的流逝以及您的需求的发展,它的回报越来越多。如果一个项目涉及多个开发人员,则尤其如此。如果要更改为新项目,是否要成为排队系统的支持人员?使用工具可以防止这种情况的发生。这成为别人的问题。

例子:持久性。编写用于在磁盘上存储一条消息的工具很容易。编写一个在许多不同的用例中可伸缩且性能良好稳定地运行,易于管理且支持成本低廉的持久化器很困难。如果您想看到有人抱怨它有多难,请查看以下内容:http : //www.lshift.net/blog/2009/12/07/rabbitmq-at-the-skills-matter-functional-programming-exchange

无论如何,我希望这会有所帮助。一定要编写自己的工具。许多人都这样做了。解决您的问题的任何方法,都是好的。


1
还是编译器。当人们总是可以编写纯净的汇编语言时,为什么还要使用一种编译语言呢?:-)
Jeff Hammond

18

我正在考虑自己使用ZeroMQ-因此我偶然发现了这个问题。

现在让我们假设您有能力实现满足所有需求的消息排队系统。为什么您会采用“自行购买”方法而不采用ZeroMQ(或其他第三方库)?简单-成本。

让我们暂时假设ZeroMQ已经满足您的所有要求。所有需要做的就是将其集成到您的构建中,阅读一些文档,然后开始使用它。这比自己动手要少得多。另外,维护负担已转移到另一家公司。由于ZeroMQ是免费的,因此就像您刚刚壮大了开发团队,使其包含ZeroMQ团队(属于该团队)。

如果您经营软件开发业务,那么我认为您可以平衡使用第三方库的成本/风险与自己开发自己的库之间的风险,在这种情况下,使用ZeroMQ会很容易。

也许您(或者更确切地说,您的伴侣)像许多开发人员一样遭受“此处未发明”综合症的折磨?如果是这样,请调整您的态度并重新评估ZeroMQ的使用。就个人而言,我更喜欢“在其他地方自豪地发现”的态度所带来的好处。我希望能为找到ZeroMQ感到自豪...时间会证明一切。

编辑:我从ZeroMQ开发人员那里看到了这段视频,讨论了为什么应该使用ZeroMQ。


我倾向于在某种程度上同意您的观点。.自从问了这个问题以来,我在过去几个月中一直在C ++中使用一些程序..而且我一直运行到第3方库。无痛..但是很多它们增加了更多的麻烦,而不是他们值得的..只是试图安装它们。我仍然不确定为什么有人会要求zeroMQ ..我学会写的第一件事就是如何通过一个非常简单的聊天程序通过TCP和套接字将消息从一个程序发送到另一个程序,这相对容易..
Evil Spork 2010年

1
完全同意,许多(也许是大多数?)第三方库比它们值得的麻烦更多。我想这些年来我发现了一些真正的宝石,我很乐意与他们合作。我刚刚编译了ZeroMQ并运行了他们的测试。看起来不错。它现在还没有“宝石”状态,但我们会看到...
Daniel Paull 2010年

1
只是为了跟进-我发现ZeroMQ相当不错。它肯定是重量很轻而且速度很快。我不喜欢它们的套接字具有线程相似性的方式,因为我想使用两个线程来访问套接字-一个用于读取消息,一个用于编写消息。它认为执行此操作的“ ZeroMQ”方法是使用进程内消息队列来封送线程之间的消息……这是需要更多考虑的。
丹尼尔·保罗

有趣,请分享更多经验!
Evil Spork,2010年

1
昨天我花了很多时间为基于Boost.Asio(boost.org/doc/libs/1_37_0/doc/html/boost_asio.html)的应用程序编写了一种替代消息传递实现。这更适合我的需求。我尚未评估它的性能,但我希望它会很好。我认为,假设您不需要它们的全部成果(例如发布/订阅模式),但使用ZeroMQ一样容易,但是文档要好得多。
Daniel Paull 2010年

6

是什么使它们比编写您自己的库更好?

消息队列系统是事务性的,从概念上讲,它易于用作客户端,但很难作为实现者使用,特别是考虑到持久队列。您可能会认为您可以编写一个快速的消息传递库,但是如果没有事务和持久性,您将无法获得消息传递系统的全部好处。

在这种情况下,持久性意味着消息中间件在服务器发生故障时将未处理的消息保留在永久存储中(在磁盘上)。重新启动后,可以处理消息,而无需重新传输(发送者甚至都不知道有问题)。事务性意味着您可以以事务性方式从不同的队列中读取消息并将消息写入不同的队列,这意味着所有读取和写入均成功,或者(如果一个或多个失败)均不成功。这与与数据库接口所知道的事务性并没有太大区别,并且具有相同的好处(它简化了错误处理;如果没有事务,则必须确保每个单独的读/写都成功,并且如果一个或多个失败,则说明回滚那些确实成功的更改)。


1
我已经考虑了片刻。事务和持久性到底是什么意思?我理解这里的词语,但不理解上下文。简而言之,它嗡嗡作响。
Evil Spork,2009年

2
我不会称这些流行语。在这些名称下,持久性和事务性已经知道了几十年了。我已经编辑了答案,以便在消息传递的上下文中详细说明这些要点。
PMF

有趣,但是什么使这些难于正确?从我的角度来看,如果我正在编写服务器和客户端,则可以发送消息,确保已收到全部消息,并将消息的副本保存到磁盘上。到此为止。为什么有这么简单的系统有这么多版本?我的意思是,其中很多都是明智的代码,一旦您了解了它们的工作原理,似乎并不需要那么多的实现。因此回到了为什么要使用预先编写的消息队列的问题。
Evil Spork,2009年

如果您不关心延迟和/或正确性,则交易非常容易实现。请参见此处,以了解一些典型的实施挑战的概述:jroller.com/pyrasun/category/XA
ddimitrov 2010年

如果我正确理解了官方的zeromq指南,则该指南不是永久性的。您必须在此基础上建立持久性。
罗宾·格林

4

在编写自己的库之前,请在此处阅读《 0MQ指南》:http: //zguide.zeromq.org/page : all

很有可能您将决定安装RabbitMQ,否则您将使它们的库位于ZeroMQ之上,因为它们已经完成了所有困难的部分。


2
他们在指南中以教程的方式做了一些“硬性部分”(例如持久性)。我宁愿使用经过考验的实现,也不愿使用一些未经测试的教程代码。
罗宾·格林

1
如果您需要经过实战检验的实现,则可以选择AMQP而不是ZMQ,并使用RabbitMQ之类的东西
Michael Dillon

2

如果您有一点时间,请尝试一下自己的解决方案!对这一专业知识的学习将使您相信使用已经经过测试的库的智慧。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.