我同时设置了ASP.NET应用程序和工作者角色,现在我想知道如何在它们之间进行通信?我认为这个想法是解决方案将分布在不同的地理位置。那么如何以简单有效的方式链接分布式Worker和Web角色呢? 我已经开始研究WCF,但它看起来像是一个过度杀伤和过于复杂的东西。我的另一个想法是使用Worker角色内的SignalR客户端与Web角色中的服务器进行通信。
修改
具体情况:
1)用户将文件上传到服务器
2)服务器将文件发送到Azure存储并将文件名添加到CloudQueue
3)Worker从CloudQueue
获取文件名4)Worker启动一个新的Thread,它从Azure Storage获取文件并开始处理它
5)工作人员/线程在文件处理的每一步报告回应用程序
6)应用程序接收报告并使用SignalR将处理步骤实时转发到客户端的浏览器。
我缺少的是步骤2> 3,如何立即通知工人新文件已到达?我不想轮询CloudQueue,因为它会造成延迟。 同样在步骤5> 6,工作人员需要通知应用程序有关步骤,这应该没有延迟,但我再也看不到在这种情况下如何使用轮询解决方案。
答案 0 :(得分:1)
如上所述,需要更多的上下文。您基本上有两个主要选项,Windows Azure队列和Windows Azure服务总线队列/主题。我的个人建议是,如果Web和工作者角色位于同一区域,则使用Azure队列,如果不是,则使用服务总线队列。我不得不问你为什么不将你的Web和工作者角色放在一起,如果你有地理部署你的应用程序然后看看在每个区域部署所有的Web角色和工作角色,例如美国,欧洲和美国亚洲然后使用流量管理器将用户路由到最佳区域。
有一篇关于何时使用哪个队列'Windows Azure队列和Windows Azure服务总线队列 - 比较和对比'的博客文章:http://msdn.microsoft.com/en-us/library/windowsazure/hh767287.aspx
HTH
修改强>
下面是一个很好的Web和工作者角色通信方法(我从@smarx最近回答的一个帖子中偷了这个)
1 Web角色将消息写入包含作业ID的队列。
2 Worker角色完成工作并将结果写入带有分区键的表。
3 Web角色正在轮询该表的那一行。一旦它存在,答案就会回来。
在您的情况下,您可以让工作者角色使用状态更新来更新表存储,然后让您的Web角色选择它们并将其显示给用户。例如20%,50%,完成等...
只要您从Web角色中充分轮询(*注意交易成本),我就不会看到此类通信的延迟
我认为可以在这里进行某种角色间的通信以进行状态更新,但这可能是过度的IMO:
http://msdn.microsoft.com/en-us/library/windowsazure/hh180158.aspx
答案 1 :(得分:0)
我建议您查看CQRS,它代表Command Query Responsibility Segregation。
这种架构的目的是创建松散耦合,可扩展和可扩展的系统。
http://cqrsjourney.github.com/
Greg Young发明了这个系统,并且有许多开源实现可用于加速分布式可扩展系统的构建。在他之前是Bertrand Meyer,他奠定了基础。
过度简化的概念是一系列队列将Web角色和工作者角色分开。因此,当用户从Web角色提交工作时,该工作将排队,然后由工作人员角色选择。权衡是最终的数据一致性,而不是直接的一致性。它的好处是松散耦合和可扩展。如果队列开始变得太大,可以添加额外的工作者角色来处理额外的规模。
该方法使用命令,查询,域对象等概念。 CQRS正在成为实现我认为您正在寻求的目标的极其强大的方式。
搜索引擎可以为您提供许多优质资源。以下是一些有用的视频: 格雷格杨 http://www.youtube.com/watch?v=KXqrBySgX-s 我的朋友Rinat http://www.youtube.com/watch?v=CnvO_nlvrps
祝你好运!答案 2 :(得分:0)
我使用azure表存储作为工作者角色和Web角色之间进行通信的地方。基本上,Worker角色会将消息/通知存储到azure表中,而web角色将有一个定时器来定期检查azure表中的更改。之后,该Web角色将使用SignalR实时向客户端页面发送消息,以报告进度。
Global.asax.cs文件:
private static System.Timers.Timer _timer;
protected void Application_Start()
{
//Start the timer job
_timer = new System.Timers.Timer(3000);
_timer.Elapsed += new ElapsedEventHandler(WebRoleTimerJob);
_timer.Start();
}
/// <summary>
/// This event will be fired intervally every 3 seconds to broadcast messsage to all registered client pages using SignalR
/// </summary>
public static void WebRoleTimerJob(object sender, ElapsedEventArgs e)
{
// Here, you can read Azure table storage to detect any changes
// or notification from Worker role
// ....
//If there is any changes, then broadcast message
// to all relevant client pages using SignalR
var context = GlobalHost.ConnectionManager.GetHubContext<Hub>();
context.Clients.All.addNewMessageToPage("your_message_name", "message_content");
}