ASP.NET MVC Web サイトで Facebook のような通知システムを作成しようとしています。
シナリオでは、通知システムは次のように機能します
- User1 は、MVC サイトのフォロー ボタンをクリックして User2 をフォローします。
- MVC サイトはAPI リクエストを介して
NotificationItem
に送信します。NotificationManager
POST api/通知/送信
NotificationManager
次に、この notificationItem を処理してから、Azure テーブル ストレージに保存します
class NotificationManager { void SaveNotification(NotificationItem item) { // save it to azure table storage } }
NotificationHub
項目を保存した後、クライアント (User2) は(SignalR ハブ)を介して notificationEvent をサブスクライブします。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); } }
この画像の現在のプロセスとアーキテクチャを説明しようとしました
さて、私を悩ませているのは、ステップ番号5のこのコード行です
var notificationData= await _repo.GetProcessedNotificationDataAsync(recipientId);
背後で行うことはnotificationItem
、ストレージからクエリを実行し、それを処理してユーザーが読み取り可能な通知 (ei. "User1 is now follow you") を処理し、notificationItem
(IsSent、DateSent) のステータスを更新します。
言うまでもなく、なんとなく「重い」動作をします。また、各サブスクライバーに配信またはブロードキャストする新しい NotificationItem があるたびに、リアルタイムでトリガーされます。
明らかに、ここではパフォーマンスとスケーラビリティの問題について話しています。そこで、この問題を解決できる可能性のある技術またはアプローチを調査しました。そして、Azure Service Bus バックプレーン アプローチを使用することが実行可能なオプションのようです
Azure Service Bus を使用した SignalR スケールアウト
特定の段落で、このアプローチのいくつかの制限について説明しています
サーバー ブロードキャスト (例: 株価情報): サーバーがメッセージの送信速度を制御するため、バックプレーンはこのシナリオに適しています。
クライアントからクライアントへ (例: チャット): このシナリオでは、メッセージの数がクライアントの数に比例する場合、バックプレーンがボトルネックになる可能性があります。つまり、より多くのクライアントが参加するにつれて、メッセージの速度が比例して増加する場合
高頻度のリアルタイム (リアルタイム ゲームなど): このシナリオでは、バックプレーンは推奨されません。
さて、私の場合のように、これは私に考えさせました。Server Broadcast と Client to Client (およびその間の何か) は、私が達成しようとしていることに適用できます。
これらは、私が現在取り組んでいる通知イベントのシナリオ (およびその受け入れ基準) です。
- ユーザーに新しいフォロワーを通知する(リアルタイムまたはほぼリアルタイムの通知)
- チャット メッセージ(リアルタイム、チャット者が現在入力しているかどうかを確認します)
- ステータスを投稿する(リアルタイムまたはほぼリアルタイム)
- 投稿にコメントする(リアルタイムで、おしゃべりが現在入力しているかどうかを確認できます)
何時間も考えた後 - 今頭にあるのは(経験不足の結果として)このような通知システムです
お気づきのとおり、これは現在のデザインとは大きく異なります。現在の設計では、Azure Webrole を 1 つだけ使用します。
これにwebrole
は、Web サイト用の 、ハブ用の webrole、および通知データを処理するための worker ロールがあります。したがって、「負荷」を3つの異なる役割に分散し、可能性を開くscaling-out.
今、これが私の頭の中での質問です。
- このアーキテクチャは、私が達成しようとしているものに適していますか?
- 通知はキューにあるので、これで「リアルタイム」の通知更新を実現できますか?
- SignalR ハブを別の Web ロールに分離したので、承認をどのように処理するのでしょうか?
- サービス バス キューですか、それとも Azure キューですか?
どんな助けでも大歓迎です。
注: このプロジェクトは実際には Azure および .NET 指向であるため、Azure テクノロジのみを使用するつもりです。