1

JMS (Java Messaging System) に似た独自の SOA スタイルのメッセージング システムを作成する方法を考えています。

MOM (メッセージング指向ミドルウェア) はメッセージを単一のデータベースに格納する必要がありますが、スケーラビリティとフェイルオーバーのために複数のサービスによって処理される場合があります。

基本的な Messages テーブルを次のように定義しました。

  1. MessageId int
  2. CreateTimeStamp 日時
  3. DeliveredTimeStamp 日時
  4. ペイロード varchar(最大)
  5. 有効期限
  6. RetryCount int
  7. 相関 ID int
  8. State int (1 - 待機中、2 - 処理中、3 - 送信済み、4 - 再試行、5 - 失敗)
  9. *ProcessIdLock int - メッセージを処理しているメッセージング サービスのプロセス ID です。

問題は、べき等性の問題は別として、1 つのサービスが一度に各メッセージを処理することを保証するにはどうすればよいかということです。

次のようなスキームを考えていました。

  1. レコード ロックの実行: UPDATE メッセージ SET ProcessIdLock = MessageProcessorId, SET State = 2 -- Processing WHERE MessageId IN ( SELECT TOP 10 MessageId FROM Messages WHERE Expiration < GETTIME() + CreateTimeStamp AND St​​ate = 1 -- Waiting OR State = 3 -- Retry )

    上記の手順では、1 つのサービスで一度に最大 10 個のメッセージを処理できます。

  2. ロックされたレコードを取得します: SELECT Payload FROM Messages WHERE State = 2 -- Processing AND ProcessIdLock = MessageProcessorId

  3. 処理された各メッセージのステータスを更新します。UPDATE Messages
    SET State = (Pass、Fail、または Retry)、SET DeliveredTimeStamp = GETDATE() -- Pass only WHERE MessageId = ProcessedMessageId

注: 私が抱えているもう 1 つの問題は、いくつかのメッセージが id でグループ化された複数のクライアントにブロードキャストされることです (つまり、合計 100 のクライアントが存在する可能性がありますが、各クライアント グループは 10 以下で構成されます)。

たとえば、グループに 5 つのクライアントがあり、現在 2 つのクライアントが切断されている場合はどうなりますか? それらのクライアントが戻ってきたら、そのメッセージを送信したいと思います。

一方のクライアントは再接続する可能性があり (メッセージを取得する必要があります)、もう一方のクライアントは再接続しない可能性があります (そのため、メッセージの有効期限が切れた後、メッセージは破棄されます)。

これを読んでくれてありがとう。私には典型的な企業の問題のように思えます。MSMQ は最適なソリューションでしょうか? 私は MSMQ を初めて使用します。MSMQ メッセージはストレージに保持されますか、それともメモリに保持されますか?

4

2 に答える 2

2

あなたの質問に直接答えるものではないことは承知していますが、ここで車輪を再発明しないことを強くお勧めします. 信頼性が高く、耐久性があり、スケーラブルなメッセージング システムを作成することは、簡単にできることではありません。代わりに、 NServiceBusなどの既存のオープン ソース実装を調べることをお勧めします。

于 2012-04-04T17:46:21.627 に答える
0

デビッド・ネルソンに同意します。そうする本当に正当な理由がない限り、既存のソリューションを検討します。NServiceBus に加えて、MassTransitもチェックアウトできます。

于 2012-04-04T22:51:52.617 に答える