使用SignalR和Azure的实时通知系统

Lin*_*ela 9 asp.net azure signalr azureservicebus azure-servicebus-queues

我试图在我们的ASP.NET MVC网站上制作类似facebook的通知系统

在一个场景中,通知系统的工作方式如下

  1. User1通过单击MVC站点中的跟随按钮来关注User2
  2. MVC站点发送NotificationItemNotificationManagervia API请求.

POST api/notifications/send

  1. NotificationManager 然后处理此notificationItem,然后将其保存到Azure表存储
   class NotificationManager { 
               void SaveNotification(NotificationItem item) { 
                 // save it to azure table storage
                } 
   }
Run Code Online (Sandbox Code Playgroud)
  1. 保存项目后,客户端(User2)然后通过NotificationHub(SignalR集线器)订阅notificationEvent

  2. NotificationHub然后通知User2以及处理过的通知数据.

 class NotificationHub: Hub {
       async Task NotifyUser(string recipientId) {

         // query data from storage and then process it
         var notificationData= await _repo.GetProcessedNotificationDataAsync(recipientId);

         Clients.Group(recipientId).notifyUser(notificationData);

      }
}
Run Code Online (Sandbox Code Playgroud)

我试图在这个图像上说明CURRENT过程和架构 在此输入图像描述

现在,困扰我的是第5步中的这行代码

 var notificationData= await _repo.GetProcessedNotificationDataAsync(recipientId);
Run Code Online (Sandbox Code Playgroud)

它背后的作用是查询notificationItem存储,将其处理为用户可读通知(例如"User1现在跟随你"),然后更新notificationItem后面的(IsSent,DateSent)状态.

不用说,它以某种方式执行"重"操作.而且它会实时每次有交付或广播给每个用户一个新的NotificationItem时间被触发.

显然,我在这里谈论性能和可伸缩性问题.所以我研究了一些可以解决这个问题的技术或方法.并且似乎使用Azure Service Bus背板方法是一个可行的选择

使用Azure Service Bus的SignalR Scaleout

SignalR中的Scaleout简介

一个特定的段落解释了这种方法的一些限制

服务器广播(例如,股票代码):背板适用于此场景,因为服务器控制消息的发送速率.

客户端到客户端(例如,聊天):在这种情况下,如果消息数量与客户端数量成比例,则背板可能成为瓶颈; 也就是说,如果消息的速率随着更多客户端的加入而成比例增长

高频实时(例如,实时游戏):不建议在这种情况下使用背板.

现在 - 这个让我思考,就像我的情况一样.服务器广播和客户端到客户端(以及介于两者之间的东西)适用于我想要实现的目标.

这些是我目前正在处理的通知事件方案(及其验收标准)

  1. 通知用户新关注者(实时或近实时通知)
  2. 聊天消息(实时,将查看聊天者当前是否正在打字)
  3. 发布状态(实时或接近实时)
  4. 在帖子中评论(实时,将查看聊天者当前是否正在打字)

经过几个小时的思考 - 我现在的想法(由于我缺乏经验)是一个类似这样的通知系统 在此输入图像描述

正如您将注意到的,这与我们当前的设计截然不同.目前的设计仅使用1个Azure webrole.

在这里,webrole网站是a,集线器的webrole,以及处理通知数据的辅助角色.因此 - 将"负载"分配给3个不同的角色以及为其打开可能性scaling-out.

现在 - 这是我现在的问题.

  1. 这个架构是否适合我想要实现的目标?
  2. 由于通知在队列中 - 我们可以实现"实时"通知更新吗?
  3. 由于我们将SignalR中心与另一个Web角色分开 - 我们将如何处理授权?
  4. 服务总线队列或Azure队列?

任何帮助将不胜感激.

注意:我打算只使用Azure技术,因为这个项目实际上是面向Azure和.NET的.

Isu*_*eka 0

  1. 是的,对于负载平衡场景,您的架构看起来应该能够完成这项工作。
  2. 如果您使用 ServiceBus Queue,那么您可以非常轻松地集成(使用 nuget 包 SignalRChat Microsoft.AspNet.SignalR.ServiceBus)
  3. 假设您的应用程序是无状态的,并且 auth cookie 仍然对这两个角色有效(假设它们位于负载平衡场景之后),则 Auth 也可以。
  4. 服务巴士。以下是有关其如何完成的更多信息。http://www.asp.net/signalr/overview/performance/scaleout-with-windows-azure-service-bus