サード パーティの Web サービスと対話する Rebus メッセージ ハンドラーがあります。すぐには制御できない理由により、この WCF サービスは、独自のデータベースでデータベース デッドロックが発生したため、頻繁に例外をスローします。その後、Rebus はこのメッセージを 5 回処理しようとします。これは、ほとんどの場合、5 回のうちの 1 回が幸運であり、デッドロックに陥らないことを意味します。しかし、メッセージがデッドロックに続いてデッドロックになり、エラー キューに入ることがよくあります。
長期的な目標となるデッドロックの原因を修正する以外に、次の 2 つのオプションが考えられます。
成功するまで、この特定のメッセージ タイプのみを試してください。できればタイムアウトを設定できるので、継続的に試行してプロセスをさらに詰まらせるのではなく、「デッドロックが 5 回発生した場合は 5 分後に再試行してください」とします。私はすでに Thread.Sleep(random) を実行してメッセージをいくらか広めていますが、5回試行してもあきらめます。
この特定のメッセージ タイプを、メッセージを処理するワーカーが 1 つしかない別のキューに送信して、これが並列ではなく逐次的に行われるようにします。現在の構成では 8 つのワーカー スレッドを使用していますが、Web サービスが同時に呼び出され、メッセージが相互に干渉するため、デッドロックの状況が悪化するだけです。
オプション#2が私の好みですが、これが可能かどうかはわかりません。現在、受信側の構成は次のようになっています。
var adapter = new Rebus.Ninject.NinjectContainerAdapter(this.Kernel);
var bus = Rebus.Configuration.Configure.With(adapter)
.Logging(x => x.Log4Net())
.Transport(t => t.UseMsmqAndGetInputQueueNameFromAppConfig())
.MessageOwnership(d => d.FromRebusConfigurationSection())
.CreateBus().Start();
そして、受信側の .config :
<rebus inputQueue="app.msg.input" errorQueue="app.msg.error" workers="8">
<endpoints>
</endpoints>
</rebus>
構成からわかることから、「リッスン」する入力キューを 1 つしか設定できません。流暢なマッピング API を介してこれを行う方法を実際に見つけることもできません。それも入力キューとエラーキューを1つだけ取るようです:
.Transport(t =>t.UseMsmq("input", "error"))
基本的に、私が探しているのは、次のようなものです。
<rebus workers="8">
<input name="app.msg.input" error="app.msg.error" />
<input name="another.input.queue" error="app.msg.error" />
</rebus>
私の要件を処理する方法に関するヒントはありますか?