使用 Windows Azure 的基于消息的体系结构

Posted

技术标签:

【中文标题】使用 Windows Azure 的基于消息的体系结构【英文标题】:Messages-Based architecture with Windows Azure 【发布时间】:2011-11-10 12:50:09 【问题描述】:

我正在 Windows Azure 上制作基于 Web 的系统,它处理来自不同来源的订单 - 网站或 Web 服务。我脑海中出现的第一件事是使用 Azure 消息队列从网站和 Web 服务角色到一些实际处理订单的工作角色。

我发现了几篇关于使用 Azure 的消息驱动架构的文章,它们看起来不错 - 我们从客户端获取消息,将其放入队列并在该工作线程读取之后响应用户“好的,您的操作已处理”消息并做所有的魔术。 但是这是一个问题 - 如果我想发送消息的处理结果(如果是成功则为订单 ID,如果不是则失败原因)作为对客户端的响应,我需要等到Worker Role 将处理它。问题是我没有找到好的/快速/便宜的方法来做到这一点,作为一种可能的方式我可以将消息放入处理队列并检查每个 X 毫秒是否已经处理(处理完成后,Worker 会将带有 Y Guid 的消息与结果一起处理的信息。

我不太喜欢这种等待的想法,因为订单处理时间可能从几秒到几分钟不等,如果每个客户(最多同时有 10 到 20 个)会增加系统负载检查每个 X 毫秒是否处理了他的请求(主要原因)。考虑到 Azure 表的访问率(次要原因),它也会非常昂贵。

您能否建议一些实现该功能的好方法?我正在寻找桌面应用程序中的事件等待之类的东西,鉴于高度分布,无法使用 Azure 制作。

【问题讨论】:

【参考方案1】:

您要做的是让 socket.io 从浏览器连接到 Web 服务器,这样您就可以立即做出响应。有一个用于 .NET 的彗星库,我从未使用过,http://pokein.codeplex.com/。我一直在 Node.js 中完成该部分,这在 Azure 上可能是可行的,但可能需要一些努力才能使其运行。 Node 有一个很棒的处理 socket.io 连接的实现。

Web Request -> MQ -> Web Services -> Process Order -> Web Server 或 MQ 上的 Web Services -> Socket.io/comet -> Web 浏览器。随着事件的发生,所有实时。

如果你让使用浏览器继续浏览网站,只是弹出一条消息,如“您的订单已处理,请在此处查看结果,当您准备好时”,结果通常是相当不错的。

【讨论】:

感谢@Travis 的建议,它看起来对网站部分来说还不错!但问题是它对 Web 服务的用户(系统用户中最大的一部分)效果不佳。 如果您需要阻止以等待它完成,在 .NET 上,我认为您在没有自己滚动的情况下会被卡住。它会占用线程轮询或等待响应。 寻找这种等待的方法是最初问题的原因 - 问题是#1 角色正在将消息放入 Azure 队列,而#2 角色正在处理它并产生结果。因此,从 #1 角色检查 #2 角色是否完成工作的方法并不多,其中之一是通过消息 Guid 检查 Azure Table,但正如我所提到的,从成本和性能的角度来看,它是昂贵的(# 1 角色需要定期检查 Azure 表,直到得到结果)。问题是#1 角色是否有办法订阅某些事件,当#2 角色完成它的工作时会触发? nservicebus.com 是一个支持此类事情(发布/订阅消息传递)的企业服务总线。有人为 Azure 编写了连接器,所以它应该可以在 Azure 上运行。还有masstransit-project.com,它的许可更加宽松,但是,我不知道有任何 Azure 传输连接器用于它。 (虽然可能不太难写)。【参考方案2】:

您所描述的方法当然是做这类事情时通常推荐的方法。

另一种方法是让角色实例直接相互通信。如果您愿意使用App Fabric Queues(目前仍在CTP 中),那么this blog post 对设置角色间通信有很好的描述。

我确信这会与其他答案中提到的服务总线选项产生类似的结果。

【讨论】:

感谢您的链接,从他们那里得到了很多想法。【参考方案3】:

在 Web 角色和辅助角色之间使用 TCP(套接字)。如果请求可能很慢,则将其设为异步 IIS 请求(例如,使用 MVC AsyncController)并让 .Net 线程处理 Web 角色 TCP 代码。您还可以全力以赴并异步编码套接字。

您当然需要在辅助角色上配置一个内部端点,并使用 Azure 分配给它的端口(请参阅 RoleEnvironment.Roles)。

【讨论】:

关于角色之间的套接字的有趣想法,我只需要检查 Azure 是否不会通过 Firewals 限制此类连接 - 谁知道,数据中心内部使用哪种架构,恐怕我无法只需知道角色的 IP 地址即可打开 TCP 连接,因为我认为它们不是静态的。 如果您使用内部端点并且角色在同一个服务中,您可以发现这些端点的IP地址并与它们进行愉快的交谈。

以上是关于使用 Windows Azure 的基于消息的体系结构的主要内容,如果未能解决你的问题,请参考以下文章

使用 Windows Azure 服务总线进行消息路由

使用 Windows Azure 队列锁定队列中的消息

(Windows Azure) 消息队列 - 多台机器上的事件

初码-Azure系列-存储队列的使用与一个Azure小工具(蓝天助手)

使用 Windows.Azure.ServiceBus (5.2.0) 的 ServiceBus 消息处理程序无法使用 DataContractSerializer NET 4.6.1 反序列化正文流

微软 Windows 11 预览版已登陆 Azure 虚拟桌面