如何在现实生活场景中使用消息队列?

Posted

技术标签:

【中文标题】如何在现实生活场景中使用消息队列?【英文标题】:How to use message queueing in a real-life scenario? 【发布时间】:2012-04-18 16:35:28 【问题描述】:

好的,所以我对消息队列感兴趣。我真的已经对这个主题进行了大量研究。我阅读了“programming windows azure”(关于 Azure 队列),阅读了大量有关 Azure 服务总线的教程和信息,还观看了有关消息传递模式的第 9 频道视频等。

但我只是不明白:在现实生活场景中如何使用它?所有示例都只是将单个字符串或带有一些数据的对象放入队列中,然后从“另一端”的队列中读取它。但是你怎么知道如何处理这些数据?例如:我可以尝试将客户、订单和地址保存到数据库中,因此我将这 3 个对象放在一个队列中以读取另一端并将它们放入我的数据库中。我怎么知道如何处理这些对象?

我有几个问题:

    将什么样的数据放入队列。可能是一个命令,它在读取时执行,所以队列中的所有内容都具有相同的接口,并且对象本身会确定要做什么? 在哪些层之间使用队列?我正在考虑将内容放入服务层的队列中(在验证之后)并在数据访问层中读取它,以便将其放入数据库中。 一个人应该排多少个队列?你想连接的层之间只有一个队列,或者它们之间有多个队列(可能出于不同的目的,虽然我想不出任何)? 这种松散耦合形式允许我们对请求进行排队,以便稍后处理它们(例如:当我们想要重新启动数据库时)。这很酷,但是如果我想读取数据而不是写入数据怎么办?那么数据库应该是在线的。我应该通过队列读取数据,还是我的服务层只是从数据访问层提取数据并将其传递给表示层?

我认为这是我脑海中嗡嗡作响的大部分问题。我希望任何人都可以为我解决这个问题。

【问题讨论】:

【参考方案1】:

在最简单的示例中,假设您将想要执行的操作序列化到队列中,然后是参数的序列化版本:

问:Delete: User 5

这很好,因为您的 Worker Role 可以阅读并采取相应措施。在这个例子中似乎不是一个很大的好处,因为排队可能需要与删除一样长的时间,但是如果您想对所有用户执行 BI 怎么办?在等待同步请求进行处理时,您的网页或应用程序永远不会刷新。但是,如果您将该请求推送到队列中:

问:RunSome2HourProcess: User *

现在您可以返回您已将操作排队,然后继续您愉快的方式,而从队列中拉出的服务器将能够在空闲时处理。

更重要的是,这可以实现更好的规模化场景。如果最后一条消息被拆分怎么办?因此,您不是针对所有用户,而是执行以下操作:

QRunSome2HourProcess: User A*-M*

QRunSome2HourProcess: User N*-Z*

两个 azure worker 角色将分担负载并并行处理您的信息。

还有许多围绕重试、工作流、跨角色异步通信等的场景,但这应该会为您提供一些理由,说明排队在正确的场景中可能是好的。

因此,在这些示例中: 1. 我们已将操作和标识符/查询放入队列项中。从队列中轮询的工作者角色会知道如何处理它。

    您可以在服务层和处理层之间使用队列。您可以在处理层之间使用队列。您可以在同一层中使用队列。天空是极限

    我通常为每个操作创建 1 个队列。所以在上面的例子中,我有 Run2HourProcess 队列,只需将参数写入它。并为任何其他进程类型创建一个新队列。但它们非常灵活,所以这取决于开发人员。

    除非是长时间运行的读取(即示例中的缩略图生成示例或数据处理速度慢的结果),否则您访问数据库的速度也一样快。

【讨论】:

感谢您的帖子。我想我有点误解:我理解为什么要使用消息队列,我只是不知道其他人在实践中是如何做到的(所以问题是:我什么时候应该创建一个新队列,我应该在队列等)。但据我了解,您为您喜欢执行的每个操作创建一个新队列。这不会迫使你拥有大量的工人吗?据我所知,在使用 Windows Azure 时您必须为每个工作人员付费,因为每个工作人员都需要自己的计算实例(服务器)。 @LeonCullens 一个“工人”角色可以运行许多不同的工人任务。您只需要为此分派不同的线程。您甚至可以组合 Worker 和 Web 角色,但不建议这样做。有关 FLUENT 工作代码的 MSFT 模式和实践示例,请参见此处:wag.codeplex.com 和 microsoft.com/downloads/en/…【参考方案2】:
    嗯,你可以在里面放任何你想要的东西。这只是一个消息,所以无论你的层同意什么都会起作用。我们会在消息中注明何时应发送电子邮件、何时需要处理视频等。 我不一定会考虑层之间的排队,而是考虑在面向用户的实时进程(例如,Web 服务器)和后台处理之间排队。使用排队来做您不希望您的 Web 角色在用户等待时花时间做的事情。 您可以制作任意数量的产品,真的。如果队列消息有一个字段说明它们的含义,那么您可以假设将所有内容放在一个队列中,尽管我不一定建议这样做。我们有大约六个队列:一个用于发送通知,一个用于视频处理,一个用于报告生成请求,等等。 我绝对不会使用队列作为数据存储和检索。这只是该工作的错误工具,例如尝试使用 TCP 存储数据。

请注意,单个工作实例(即 VM)可以读取任意数量的队列。您只需要以这种方式编写代码。如果您有很多没有看到太多流量的队列,那么这是降低成本的合理方法。另一种选择是将几种消息类型组合到一个队列中。这样一来,您只有一个地方可以查找消息。

或者,您可以让多个工作人员从同一个队列中读取,以便将工作平均分配给他们。

【讨论】:

【参考方案3】:

除了 Rob 提到的之外,消息队列还用于处理突发流量,这些流量可以等待(在队列中)直到有空闲的 worker 可用。

我相信 Azure 服务总线、队列和主题在幕后利用消息队列来完成同样的任务。我还看到了一些提示,即 AppFabric 托管的 Workflow Foundation 也可能会这样做。

【讨论】:

感谢您的帖子。请在 Rob 的帖子中查看我的评论。

以上是关于如何在现实生活场景中使用消息队列?的主要内容,如果未能解决你的问题,请参考以下文章

互联网业务场景下消息队列架构

我爱java系列---消息队列(rabbitmq)

如何使用NODEJS+REDIS开发一个消息队列

举例说明消息队列应用场景及ActiveMQRocketMQKafka等的对比

场景应用:Redis如何做消息队列?

Redis的基本使用(二) 消息队列