(过度)使用 Azure 队列的最佳实践
我正处于设计基于 Azure 的应用程序的早期阶段。考虑到我可能预期的需求的变化性,Azure 吸引我的地方之一是它的可扩展性。因此,我试图保持事物松散耦合,以便我可以在需要时添加实例。
我看到的关于构建 Azure 应用程序的建议包括将 Web 角色逻辑保持在最低限度,并在辅助角色中完成处理、使用队列进行通信以及某种后端存储(例如 SQL Azure 或 Azure 表)。这对我来说似乎是个好主意,因为我可以毫无问题地扩展应用程序的一个或两个部分。不过,我很好奇是否有任何最佳实践(或者是否有人有任何经验),什么时候最好让网络角色直接与数据存储对话,而不是通过队列发送数据?
我正在考虑这样一种情况,我需要从网络角色进行简单的插入 - 虽然我可以将其设置为消息,将其发送到队列中,然后让辅助角色拾取它并执行插入,但它似乎有很多双重处理。不过,我也意识到,从长远来看,这可能会更好,以防 Web 角色不堪重负或插入最终需要更复杂的逻辑。
我意识到这可能是一种情况,答案是“这完全取决于情况,检查你的性能指标”——但如果有人有任何想法,我将非常感激!
I'm in the early phases of designing an Azure-based application. One of the things that attracts me to Azure is the scalability, given the variability of the demand I'm likely to expect. As such I'm trying to keep things loosely coupled so I can add instances when I need to.
The recommendations I've seen for architecting an application for Azure include keeping web role logic to a minimum, and having processing done in worker roles, using queues to communicate and some sort of back-end store like SQL Azure or Azure Tables. This seems like a good idea to me as I can scale up either or both parts of the application without any issue. However I'm curious if there are any best practices (or if anyone has any experiences) for when it's best to just have the web role talk directly to the data store vs. sending data by the queue?
I'm thinking of the case where I have a simple insert to do from the web role - while I could set this up as a message, send it on the queue, and have a worker role pick it up and do the insert, it seems like a lot of double-handling. However I also appreciate that it may be the case that this is better in the long run, in case the web role gets overwhelmed or more complex logic ends up being required for the insert.
I realize this might be a case where the answer is "it depends entirely on the situation, check your perf metrics" - but if anyone has any thoughts I'd be very appreciative!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是我的比喻,做你想做的事
想象一下你正在进入一家夜总会,它毗邻一个危险的区域,但一旦你进去了就没事了。
管理层雇佣了一些大肉保镖在门上清理那些即兴表演者。如果你是个白痴,你就进不去。这里可以随意扩展这个比喻。
如果你没问题,那么他们就会让你进门,然后你就加入,是的,在售票处排队付款才能进入实际的俱乐部。
根据足球比赛是否进行或其他什么情况,您可能需要在门口增加一些保镖,但这可以独立于票房工作人员。忙碌的夜晚,您可能会打开另一个窗口以更快地收到钱,但您可能不会做让保镖处理现金的事情。他们还有其他事情要做。
所以:
传入流量,排斥无效流量
请求并添加有效请求
到:
因此,您的网络角色没有理由不能扮演票房角色,但从长远来看,最好不要这样做,
这是我的比喻
托比
Here's my metaphor, do what you will with it
Imagine you're entering a nightclub, that borders on a dodgy area, but is alright once you're inside.
The management employ some big meaty bouncers on the door to sort out the riff raff. If you're an idiot, you're not getting in. Extend the metaphor as much as you like here.
If you're OK, then they let you in the door, and you join, yes, The Queue to pay at the Box Office to enter the actual club.
Depending if the football's on or something, you might want some more bouncers on the door, but this can be independent of the Box Office staff. Busy night, you might open another window to get the money in quicker, but what you're probably not going to do get the bouncers to handle cash. They've got other things to do with their hands.
So:
incoming traffic, repel invalid
requests and add the valid requests
to:
So, there's no reason why your web roles can't do the box office role, but it's probably best not in the long-run
that's my metaphor
Toby
我想说像插入这样的东西不需要工作者角色。无论如何,您都会向队列中插入数据,因此您不会在网络角色中保存任何内容。最好的办法是将您的插入(以及所有数据访问)隔离到 Web 角色中的一个或多个单独的类中。这将使您能够将 Web 角色中的其余代码与您正在使用的特定数据存储系统分离。这使得以后更改数据存储变得更加容易。如果您的插入最终需要更多处理,您可以在需要时添加队列和辅助角色,但我仍然会说您希望直接插入到表存储中,然后将计算或其他业务逻辑转移到工人角色。然后,该辅助角色可以处理来自队列的消息,或者只是查询表存储以获取新的(未处理的)记录。
我认为使用队列与辅助角色进行通信最有效的方式是当需要对数据进行计算或其他处理时。我最常使用的实际上是 Azure SDK 中的示例之一,它展示了如何制作缩略图。我的Web角色将上传的图像插入Azure Blob存储中,并将相关描述和其他字段插入Azure表存储中。它还会在队列中放置一条消息,让辅助角色知道有一个需要生成缩略图的新图像。实际上,我为每个图像生成了几种不同尺寸,以用于网站的不同部分。辅助角色仅生成这些缩略图,不需要将任何类型的通知发送回 Web 角色。当缩略图尚不可用时,任何使用图像的地方都有逻辑使用原始上传或其他占位符。
如果您想完全跳过队列,则同一过程可以仅使用 Blob 存储上的查询来查找哪些图像仍需要处理。我还没有确定是否喜欢使用队列或只是轮询数据以查找需要辅助角色处理的记录。我认为队列效率更高,但它也增加了额外的复杂性和额外的潜在故障点。
编辑评论:当我发布此答案时,我说如果缩略图不可用,则仅在用户界面中使用全分辨率图像。现在,我正在开发一个仅使用默认缩略图的网站,该缩略图显示“正在处理”,直到生成的缩略图可用。选择权在您手中,并且实际上取决于应用程序 UI 的要求。
您可以做的一件事是使用 SignalR 或某些 AJAX 在新缩略图可用时通知用户浏览器,而无需等待新页面加载。
在工作线程上进行图像处理时查看占位符缩略图比在生成缩略图时等待页面加载要好得多的用户体验。
I would say something like an insert doesn't require a worker role. You'd have an insert into the queue anyway, so you wouldn't be saving anything in the web role. Best thing would be to isolate your inserts (and all data access) into a separate class (or classes) within your web role. This would allow you to decouple the rest of the code in your web role from the specific data storage system you're using. That makes changing the data store later much easier. If your inserts end up needing more processing, you can add the queue and worker role when it's needed, but I would still say that you'd want to do the insert into table storage directly and then relegate the computation or other business logic to a worker role. Then that worker role can process messages from the queue or just query table storage for new (unprocessed) records.
The way I see using the queue to communicate with a worker role become most affective is when there are calculations or other processing that would need to be done with the data. The one I've been using the most is actually one of the samples in the Azure SDK that shows how to make thumbnail images. My web role inserts the uploaded image into Azure blob storage and related description and other fields into Azure table storage. It also places a message on the queue that lets the worker role know that there is a new image that needs thumbnails generated. I actually generate a few different sizes of each image for use in different parts of the site. The worker role just generates those thumbnails and doesn't need to send any kind of notification back to the web role. Any place that uses the images has logic to use the original upload or other placeholders when the thumbnails aren't yet available.
This same process could just use a query on the blob storage to find which images still require processing if you wanted to skip the queue altogether. I haven't made a determination on if I prefer using the queue or just polling the data to find records that need the worker role's processing. I suppose the queue is more efficient, but it also adds an extra layer of complexity and an extra potential failure point.
Edit in response to the comment: when I posted this answer I said to just use the full resolution image in the UI if the thumbnail isn't available. Now I am working on a site that just uses a default thumbnail image that says "processing" until the generated thumbnail is available. The choice is yours and really depends on the requirements of your app's UI.
One thing you could do is use SignalR or some bit of AJAX to notify the user's browser when a new thumbnail is available without waiting for a new page load.
Seeing a placeholder thumbnail while image processing is happening on a worker thread is much better user experience than waiting for the page to load while the thumbnail is being generated.
使用分布式队列(Azure 或 Amazon 或其他)相当微妙。我发布了一篇博客文章 涵盖 Azure 队列的常见微妙之处。底线:我建议仔细从业务逻辑(队列的内容和处理)中抽象出基础设施逻辑(支持队列)。
Using Distributed Queues (Azure's or Amazon's or else) is rather surprisingly subtle. I have posted a blog entry covering frequent subtleties of Azure Queues. Bottom line: I suggest to carefully abstract away your infrastructure logic (supporting the queue) from your business logic (content and processing of the queue).