为啥使用 AMQP/ZeroMQ/RabbitMQ

Posted

技术标签:

【中文标题】为啥使用 AMQP/ZeroMQ/RabbitMQ【英文标题】:Why use AMQP/ZeroMQ/RabbitMQ为什么使用 AMQP/ZeroMQ/RabbitMQ 【发布时间】:2010-12-21 21:01:43 【问题描述】:

而不是编写自己的库。

我们正在这里做一个项目,该项目将是一个自划分的服务器池,如果一个部分变得太重,经理会将它划分并作为一个单独的进程放在另一台机器上。它还会提醒所有受此影响的已连接客户端连接到新服务器。

我很好奇使用 ZeroMQ 进行服务器间和进程间通信。我的搭档宁愿自己动手。我期待社区来回答这个问题。

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

【问题讨论】:

你不应该编写自己的库的原因是,用你自己的话来说,你是“一个相当新手的程序员”。为什么要使用新手程序员编写的 MQ 库? 【参考方案1】:

有什么比编写自己的库更好?

在推出您的应用的第一个版本时,可能什么都没有:您的需求已明确定义,您将开发一个满足您需求的消息传递系统:小功能列表、小源代码等。

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

您的应用程序必须通过小端机器(x86、intel/amd)与大端机器(sparc/powerpc)通信。你的消息系统有一些字节序的假设:去修复它 您设计的应用程序不是二进制协议/消息系统,现在它非常慢,因为您花费大部分时间解析它(消息数量增加,解析成为瓶颈):调整它以便它可以传输二进制/固定编码

一开始你在一个局域网内有 3 台机器,每台机器都没有明显的延迟。您的客户/老板/pointy-haired-devil-boss 出现并告诉您将在您不管理的 WAN 上安装应用程序 - 然后您开始出现连接失败、延迟不佳等问题。您需要存储消息并重试发送稍后他们:返回代码并将这些东西插入(并享受)

发送的消息需要回复,但不是全部:您发送一些参数并期望电子表格作为结果,而不仅仅是发送和确认,返回代码并将这些东西插入(并享受.)

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

还有很多我忘记的用例......

您可以自己实现它,但不要花费太多时间:无论如何,您以后可能会替换它。

【讨论】:

啊,非常感谢。这当然让我深思。 根据 zeromq 官方指南,zeromq 不提供持久性。该指南向您展示了如何做到这一点,但我宁愿将一些具有持久性的东西融入框架,而不是使用一些测试不佳的教程代码! 不同意“在推出你的应用程序的第一个版本时,可能什么都没有”你最后说第一个版本无论如何都会用库重写,不妨从你没有结束的东西开始起来扔掉。否则,我同意。 @OO 大多数情况下,所需的初始功能都很小,您不能总是证明轻松导入第 3 方的东西是合理的:需要批准、对代码进行安全检查等,这取决于您为这些工作的人需要很多比开发时间更多的时间。因此,您从小处着手,使用公司中已有的工具自己动手,然后当您的代码处于 prod、大量使用时,使用 3rd 方的东西变得更容易。您的里程可能会有所不同,但通常公司不希望使用大量的第 3 方材料/框架/库。【参考方案2】:

这很像问:既然可以编写自己的数据库,为什么还要使用数据库?

答案是,使用一个已经存在了一段时间并且在许多不同的用例中都被很好理解的工具,随着时间的推移和您的需求的发展而获得越来越多的回报。如果一个项目涉及多个开发人员,则尤其如此。如果你改变一个新项目,你想成为排队系统的支持人员吗?使用工具可以防止这种情况发生。它变成了别人的问题。

恰当的例子:坚持。编写一个在磁盘上存储一条消息的工具很容易。在许多不同的用例中,编写一个可扩展且性能良好稳定、易于管理且支持成本低廉的持久化器是很困难的。如果你想看到有人抱怨它有多难,那么看看这个:http://www.lshift.net/blog/2009/12/07/rabbitmq-at-the-skills-matter-functional-programming-exchange

无论如何,我希望这会有所帮助。一定要编写自己的工具。很多很多人都这样做了。只要能解决你的问题,就是好的。

【讨论】:

或编译器。既然可以一直编写纯正的汇编语言,为什么还要费心使用编译语言呢? :-)【参考方案3】:

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

让我们暂时假设您有能力实现一个满足您所有要求的消息队列系统。为什么你会采用 ZeroMQ(或其他第三方库)而不是自己滚动的方法?简单 - 成本。

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

如果您经营软件开发业务,那么我认为您会平衡使用第三方库与自行开发库的成本/风险,在这种情况下,使用 ZeroMQ 会胜出。

也许您(或者更确切地说,您的合作伙伴)像许多开发人员一样遭受"Not Invented Here" 综合症的困扰?如果是这样,请调整态度并重新评估 ZeroMQ 的使用。就个人而言,我更喜欢 Proudly Found Elsewhere 态度的好处。我希望我能为找到 ZeroMQ 感到自豪……时间会证明一切。

编辑:我从 ZeroMQ 开发人员那里看到了这个 video,他谈到了为什么应该使用 ZeroMQ。

【讨论】:

在某种程度上我倾向于同意你的观点。自从提出这个问题以来,过去几个月我一直在使用 C++ 中的一些程序。我遇到了地狱3rd 方库..有些相对无痛..但其中很多增加的麻烦超过了它们的价值..只是试图安装它们。我仍然不确定为什么有人会对 zeroMQ 有要求。我学会写的第一件事就是如何通过 TCP 和套接字将消息从一个程序发送到另一个程序,这是一个非常简单的聊天程序,相对容易.. 完全同意许多(也许是大多数?)第三方库比它们的价值更麻烦。我想这些年来我发现了一些真正的宝石,我非常乐意与之合作。我刚刚编译了 ZeroMQ 并运行了他们的测试。它看起来很不错。它还没有“宝石”状态,但我们会看到...... 只是跟进 - 我发现 ZeroMQ 非常好。它当然重量轻且速度快。我不喜欢他们的 Socket 具有线程亲和性的方式,因为我想使用两个线程来访问套接字——一个用于读取消息,一个用于写入消息。它认为这样做的“ZeroMQ”方式是使用进程内消息队列来编组线程之间的消息......需要更多思考。 有意思,有经验请多分享! 我昨天花了很多时间为我的应用程序编写了一个基于 Boost.Asio (boost.org/doc/libs/1_37_0/doc/html/boost_asio.html) 的替代消息传递实现。这更符合我的需求。我还没有测量它的性能,但我希望它会非常好。我认为使用 ZeroMQ 很容易,假设您不需要他们所有的成果(如发布/订阅模式),但有更好的文档。【参考方案4】:

有什么比编写自己的库更好?

消息队列系统是事务性的,从概念上讲,它作为客户端很容易使用,但作为实现者很难正确使用,尤其是考虑到持久队列。您可能认为编写一个快速消息传递库可以侥幸成功,但如果没有事务和持久性,您将无法获得消息传递系统的全部优势。

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

【讨论】:

我一直在考虑这个问题。事务和持久性到底是什么意思?我明白这些话,但不明白这里的上下文。简单地说,它是流行语。 我不会称这些流行语;几十年来,持久性和事务一直以这些名称而闻名。我已经编辑了我的答案,以在消息传递的上下文中详细说明这些要点。 很有趣,但是是什么让这些很难做到呢?从我的角度来看,如果我正在编写服务器和客户端,您发送消息,确保完整接收消息,并将消息的副本保存到磁盘。这就是它的结束。为什么这么简单的系统有这么多版本?我的意思是它们中的很多都是相当小的代码,一旦你理解了它们是如何工作的,它似乎不需要那么多来实现。所以回到为什么要使用预先编写的消息队列。 如果您不关心延迟和/或正确性,事务很容易实现。有关一些典型实施挑战的概述,请参见此处:jroller.com/pyrasun/category/XA 如果我正确理解了官方的 zeromq 指南,它不是持久的。您必须在此基础上建立持久性。【参考方案5】:

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

您可能会决定安装 RabbitMQ,或者您将在 ZeroMQ 之上创建您的库,因为他们已经完成了所有困难的部分。

【讨论】:

他们在指南中以教程的方式完成了一些“困难的部分”(例如持久性)。我宁愿使用久经考验的实现,也不愿使用一些测试不佳的教程代码。 如果你想要经过实战考验的实现,那么你会选择 AMQP 而不是 ZMQ 并使用 RabbitMQ 之类的东西【参考方案6】:

如果您有一点时间,请尝试一下并推出您自己的实现!本练习的学习内容将使您相信使用已经过测试的库的智慧。

【讨论】:

以上是关于为啥使用 AMQP/ZeroMQ/RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥在参数周围使用 /*、*/ 以及为啥在提取数组长度时使用 >>>? [复制]

为啥我们使用 hadoop mapreduce 进行数据处理?为啥不在本地机器上做呢?

为啥 CoreGui Roblox 锁定在 DataModel 中,为啥受信任的用户不能使用 CoreScripts?

为啥有人应该在 git commit 之前使用 git add?或者为啥有人应该使用 git add 呢?

为啥刷新令牌更安全?如果刷新令牌也可能被盗,为啥我们还要使用它?