0

次の設定があります。デプロイされた Azure ワーカー ロールの N インスタンスがあります。デスクトップ アプリケーションがメッセージを Azure にアップロードすると、メッセージに関連する一連の画像がアップロードされます。メッセージは、必要な画像を認識しています。

これら 2 つのアクティビティ (メッセージのアップロードと画像のアップロード) は独立しています。画像は、メッセージがユーザーによって生成される前 (キャッシュと呼びますが、より複雑です)、またはメッセージが Azure にアップロードされてから数秒または数分後にアップロードできます。

メッセージは Azure MSSQL データベースに保存し、画像は BLOB に保存し、それらへの URL はデータベースに保存します。また、メッセージの画像へのリンクを格納するMessageToImageテーブルもあります。これは単純化されたDB構造です(私のC#を許してください):

class Message
{
    public int Id;
    public string Text;
}

class Image
{
    public int Id;
    public string Name;
    public string BlobUrl;   // Null if image was not received by the service yet
}

class MessageToImage
{
    public int MessageId;
    public List<int> ImageIds;
}

そして、すべての画像の準備が整った (つまり、すべての画像がアップロードされた) メッセージを受け取ったら、それを使って別のことをする必要があります (たとえば、Facebook に投稿します)。ここに質問があります:メッセージが 1 回だけ処理されることを保証するにはどうすればよいですか? 最悪のシナリオでは、メッセージの N 個のイメージを同時に受信する N 個のインスタンスがあり、どのインスタンスがその後の処理にメッセージを送信する必要があるかを「選択」しますか? そして、それが一度だけ起こることをどのように保証できますか?

これまでのところ、次のアイデアを思いつきました。

  1. 「画像の BlobUrl を更新する」データベース ロジックがアトミックであり、メッセージに対して「不足している」画像の数が返されることを確認してください。このようにして、1 つのインスタンス (データベース更新の結果として "0" を受け取るインスタンス) でのみ、さらなる処理をトリガーします。しかし: MSSQL レベルでどうすればそれを行うことができますか? さらに複雑 - Entity Framework を使用してそれを行うにはどうすればよいですか?

  2. すべての画像を含むメッセージを選択する専用のワーカー ロールを用意し、それらを処理のために送信します。しかし、それはうまくスケーリングできません...そして少し醜く見えます。

他のアイデア/提案はありますか?

ありがとう!


UPDATE1 @Richard と @Rob は、Service Bus Queue の使用を提案しました。私はそれを調べました。私がまだ答えを持っていない部分は、処理のためにメッセージをキューに送信するタイミングを決定する WORKER ROLE のコードがどのように見えるかです。すべての画像がデータベース/BLOB に存在する (つまり、Azure クラウドにアップロードされた) 場合にのみ、メッセージがキューに送信されます。ここで、コーナー ケースの例を挙げたいと思います。10 個の画像が 10 個のワーカー ロールによって同時に処理されています。すべてのインスタンスの処理が同時に終了します。各ロールは、アップロードされた画像 URL でデータベースを更新します。そして、どうにかして最終的なメッセージ処理をトリガーする必要があります。つまり、インスタンスの 1 つが優先される必要があります。そして、私はこれをどのように行うべきか明確ではありません。

これにより、私の質問が少しきれいになることを願っています。

4

2 に答える 2

2

Azure Service Bus キューを作成し、クライアント アプリがメッセージをキューに投稿するようにします。その後、worker ロールはキューからメッセージをプルしてメッセージを処理できます。

サービス バス キューの優れた点は、メッセージがキューから 1 回だけ引き出されることが保証されていることです。その後、メッセージは "取得済み" としてマークされます。トランザクションが (構成可能な) 時間内に完了したとマークされない場合、メッセージはキューに返され、次のワーカー リクエストによってプルされる準備が整います。

つまり、worker ロールが処理の途中で失敗した場合、メッセージは最終的にキューに再表示され、次のワーカーがそれを受け取り、(できれば) 必要な作業を完了することができます。

詳細については、これをお読みください。

Service Bus キューの使用方法

于 2013-05-22T23:47:12.867 に答える
1

Service Bus Messaging Sessions の使用を検討する必要があります

クライアントで、アップロード セッションの一意のバッチ アップロード ID を生成します (int ではなく GUID を使用します)。アップロードされる各画像には、この ID が付随している必要があります (アップロード バッチ内のすべての画像で同じ ID)。サービスが画像を受信すると、クライアントから提供された一意の ID に設定された SessionId を使用して、Service Bus Queue または Topic に "Upload Image" BrokeredMessage を送信します。

メッセージがクライアントからサービスに送信されるときに、バッチ アップロード ID を一緒に送信します。これがサービスから受信されると、「Process All Uploads」 BrokeredMessage を別のキュー/トピックに送信します。この BrokeredMessage の受信者は、バッチ アップロード ID を読み取り、関連する sessionId に関連付けられたすべての「Upload Image」メッセージのリッスンを開始します。それらをすべて受信するまで、これを続けることができます (いつ停止するかを知るために、アップロードされた合計数を送信する必要がある場合があります)。それらをすべて受信すると、新しい BrokeredMessage を生成して、画像アップロードの処理をトリガーできます (例: facebook への投稿)。

メッセージの処理中にロールが失敗した場合、メッセージはしばらくしてから再配信されるように、最終処理段階 (facebook への投稿) 用に別の BrokeredMessage を生成したいと考えています。

心に留めておくべきことは、メッセージは「少なくとも 1 回」受信されるということです。ロールがメッセージ処理の途中で失敗した場合、メッセージはタイムアウト後にキュー/トピックに戻ります。そのため、処理ロジックは、以前に部分的に処理されたメッセージを処理するケースを処理できる必要があります。

以下は、目的を達成するためにさまざまなアクターが行うべきことを大まかに示したものです。

クライアント

  • 一意の sessionId を生成します (または Web サービスからリクエストします)。
  • 関連付けられた sessionId を使用して、各画像を Web ロールにアップロードします
  • アップロード バッチで関連付けられた sessionId と imageCount を使用して、ジョブ「メッセージ」を Web ロールにアップロードします (画像のアップロードの前/最中/後に実行できます)。

Web ロール

  • アップロードされた画像を受信したら、画像を BLOB ストレージに保存し、キュー (「UploadsQueue」) に、SessionId が設定された BrokeredMessage と画像 URL を含む Body をポストします。
  • アップロードされたジョブ「メッセージ」を受信するとき、セッション ID と imageCount を含むボディを含む「UploadBatch」 BrokeredMessage をキュー (「JobsQueue」) にポストします。

ワーカーの役割

  • 「JobsQueue」から「UploadBatch」メッセージを受信すると、メッセージ本文から sessionId と imageCount を取得し、「UploadsQueue」で AcceptMessageSession(sessionId) を取得し、すべてのアップロード メッセージを受信するまで、そのセッションでメッセージをポーリングし続けます。一度 (receivedCount == imageCount) "SendToFacebook" メッセージを "JobsQueue" に投稿し、処理する画像のリストなどを Body に入れます。
  • 「JobsQueue」から「SendToFacebook」メッセージを受信すると、メッセージ本文から処理する画像の一覧を取得し、facebook などに送信する
于 2013-05-23T00:13:47.037 に答える