昨日、ディストリビューターとの非常に有望なテストの後で、NSB(36-80コア)のライセンスを購入するための追加予算を要求しました。
現在、配管の問題を解決するためにディストリビューターを使用しており、実際のビジネスイベントにはまだ使用していませんが、それは後で行われます。
今日、私の非常に熟練した同僚もバスを使い始めました。彼のプロジェクトの性質上、彼のパフォーマンス要求だけが私のものよりもはるかに高くなっています。したがって、彼のテストでは、ディストリビューターが現在私に提供している平均30〜50msgpr秒よりもはるかに多くの時間が必要です。
私たちがやろうとしたことは何でも:
- より多くの労働者。
- ワーカーに関するスレッドが増えました。
- ディストリビューターのスレッドが増えました。
- DTCの有効化/無効化
- 上記のすべては、IDのみを含むメッセージを使用した概念実証のセットアップです。約100msgの分散PRを取得できませんでした。労働者に次ぐ。
私はすでにより多くの予算を申請しているので、これは非常に悪いことです。パフォーマンスをすぐに上げることができない場合は、プロジェクトを中止する必要があり、深刻な問題が発生します:S。
質問:
現在使用している開発者ライセンスに制限があり、この制限が発生していますか、またはたとえばここで説明されているように、MSMQに重大なパフォーマンスの問題がありますか?http://ayende.com/blog/4251/what-am-i- missing-msmq-perf-issue。
私はnservicebus自身のサイトでライセンスについてたくさん読んでいますが、開発者ライセンスの制限についての明確な説明はどこにもありません。
誰かが私を助けてくれることを願っています:)。
[アップデート]
基本に戻り、10000個のメッセージを送信してワーカー/ディストリビューターがどのように反応するかを確認することで、NSB独自のコードサンプルScaleOutの問題を再現しようとしました。そこで、ディストリビューターと2人のワーカー(ワーカーにはそれぞれ100個のスレッドがあります)を起動し、問題が再び発生したことを推測します。
- 幸い、これは、ディストリビューター/ワーカーのセットアップが完全に間違って構成されていないことを示しています。
- 残念ながら、これはディストリビューターのパフォーマンスにまだ問題があることを意味します。
次に、これが実際に当てはまるのかどうか疑問に思い、ディストリビューターとワーカーを使用してテストを調整しながら、いくつかの単純な数のスレッドを実行し始めました。何度か試した後、サンプルで最大400〜500 msgprsecのスループットが得られました。これが私が発見したものです:
観察/解決策:
- ディストリビューターには、1つだけではなく、より多くのスレッドが必要です。現在、2つのスレッドを実行しています。労働者私は起動します。
- 20または100スレッドを実行している場合、ワーカーは通常同じパフォーマンスになります。そのため、スレッドの数を増やす代わりに、ワーカーの数を増やしました。これでうまくいきました。
- ディストリビューターまたはワーカーのいずれかのスレッドの数が多すぎると、MSMQトランザクションの競合が発生しているように見えます。そこでは、スレッドが相互にブロックし、システムがバーストで詰まります。ScaleOutサンプルと自分のコードを使用して、詰まりを簡単に再現できますが、TXの戦いは、私が読んだ記事に基づく単なる推測であり、これが起こっていることを証明するものではありません。
フォローアップの質問:
- 今何をする?MSMQを別のものに置き換える必要がありますか、それともこの問題はNSBの内部にあるものであり、後のバージョンで最適化/修正される可能性がありますか?
- これは、ディストリビューターが機能するための意図された方法ですか?つまり、私たちの唯一の解決策は、より多くの労働者を解雇することです。
- 同じエンドポイントに複数のワーカーがありますが、ディストリビューターとは異なるマシンが実行されていても、ワーカー間でMSMQ TXの競合を引き起こす可能性のある、競合するコンシューマーの状況は発生しませんか?
- サンプルと独自のコードには重要な違いが1つあります。Ravenサブスクリプションストレージを無効にし、純粋にMSMQで実行していますが、私が知る限り、ディストリビューターはストレージにRavendbを使用していません。私は間違っていますか?これはパフォーマンスを得る場所になる可能性がありますか?
ディストリビューターと同じマシンではなく、同じマシンで複数のワーカーを起動する際に問題が発生するかどうかを確認するために、現在いくつかの分散テストを実行しています。ワーカー用に追加のサーバーをすでに注文しており、それ以上の予算がないため、ワーカーごとに個別のキューを設定しなくても、これが可能になることを願っています。
これまでのところ、ワーカーのスレッド数を単純に増やして1人のワーカーから始めて、後でそれぞれ1人のワーカーを持つより多くのマシンにスケールアウトすることができないことに少しがっかりしています。現在、1台のマシンに複数のワーカーを配置する必要があります:/。
ディストリビューター/ワーカーが足りないという小さな点があれば、共有してください。これが私を夢中にさせているからです:/。
[更新2]
NServiceBus.Integration NServiceBus.Distributor / Workerと1人のワーカーを使用してVisualStudioの外部でScaleOutサンプルを実行すると、4〜500msg/秒のスループットを得ることができます。
これは素晴らしいことですが、私たちがセルフホスティングしている私たち自身のセットアップで私が間違ったことを説明していません。私たちの構成を見て、何か怪しいものがあるかどうか教えてください:
卸売業者:
var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
return NServiceBus.Configure.With()
.DefineEndpointName(queuePrefix)
.Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
.StructureMapBuilder()
.JsonSerializer()
.AsMasterNode()
.RunDistributorWithNoWorkerOnItsEndpoint()
.MsmqTransport()
.IsTransactional(true)
.DisableTimeoutManager()
.DisableSecondLevelRetries()
.UnicastBus()
.CreateBus()
.Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
ワーカー:
var queuePrefix = ConvertFriendlyNameTo.QueueName(AppDomain.CurrentDomain.FriendlyName);
return NServiceBus.Configure.With()
.DefineEndpointName(queuePrefix)
.Log4Net(ObjectFactory.GetInstance<IServiceBusLog>().Build())
.StructureMapBuilder()
.JsonSerializer()
.EnlistWithDistributor()
.MsmqTransport()
.IsTransactional(true)
.DisableTimeoutManager()
.DisableSecondLevelRetries()
.UnicastBus()
.CreateBus()
.Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
パフォーマンスの違いを引き起こす可能性のある、ここで間違っていることはありますか?
敬具。