今日は障害物にぶつかりました。私たちの組織では、すべてのデプロイは TFS Build によって行われます。各 NSB ホスト コンポーネントがパッケージ化され、ビルド ポータルによってデプロイされる場所。NSB のスケールアウト機能を使用しようとすると、マスター プロファイルおよびワーカー プロファイルと同じコンポーネントをインストールする必要があります。パッケージ化するときに必要な引数を渡すことで、Master & Worker インストーラーを管理しました。プロセスを簡素化するために、マスターとワーカーの両方に 1 つの構成ファイルを使用し、マスターとワーカーの両方の MasterNode 構成を保持することを計画しました。大丈夫だ!本当にうまくいきました。
ポリシーに従って、構成ファイルでサーバー名を使用するべきではなく、構成ファイルで DNS エイリアスを使用する必要があります。DNS エイリアス上で MSMQ の動作を有効にすることで、これを実現しました。
ここで、実際の問題が始まります。NServiceBus.Master プロファイルは、入力キューに Node 値を追加します。DNS エイリアスをノードとして使用すると、次の例外がスローされます。
System.Exception: エンドポイントの開始時に例外が発生しました。エラーがログに記録されました。理由: 入力キュー [somequeue@some-dns.bus] は、このプロセス [SOMEDITSERVER01] と同じマシン上にある必要があります。---> System.InvalidOperationException : 入力キュー [somequeue@some-dns.bus] は、このプロセス [SOMEDITSERVER01] と同じマシン上にある必要があります。NServiceBus.Unicast.Queueing.Msmq.MsmqMessageReceiver.Init (アドレス アドレス、ブール値トランザクション) で NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.NServiceBus.Unicast.Transport.ITransport.Start (アドレス アドレス) で NServiceBus.Unicast.UnicastBus. NServiceBus.Hosting.GenericHost.Start() での NServiceBus.IStartableBus.Start(Action startupAction)
--- 内部例外スタック トレースの終了 --- NServiceBus.Hosting.GenericHost.Start() at Magnum.StateMachine.EventActionList`1.Execute(T stateMachine, Event event, Object parameter)
--- 内部例外スタック トレースの終了 --- Magnum.StateMachine.ExceptionActionDictionary 1.Execute(T stateMachine, Event event, Object parameter) at Magnum.StateMachine.State 1 eevent, Object value) at Magnum.StateMachine.StateMachine` 1.RaiseEvent (発生したイベント) で Topshelf.Internal.ServiceControllerProxy.Start() で Topshelf.Internal.ServiceCoordinator.Start() で Topshelf.Internal.Hosts.ConsoleHost.Run() で NServiceBus.Hosting.Windows.Program.Main(文字列[]引数)
1.HandleException(T stateMachine, Event event, Object parameter, Exception exception)
at Magnum.StateMachine.EventActionList1.RaiseEvent(T instance, BasicEvent
質問:
NSB が現在の入力キューの有効なサーバー名として現在の MachineName を厳密に探しているときに、NSB が入力キューと他のキューに MasterNode 値を追加するのはなぜですか? NServiceBus.Master または NServiceBus.Distributor で実行するときに、なぜ NSB は MasterNode の値を無視しないのでしょうか?
それでも NSB が入力キューに MasterNode 値を追加したい場合...なぜ NSB は DNS 名を解決せず、代わりに現在の MachineName で検証を制限するのでしょうか?
var configSection = Configure.GetConfigSection<MasterNodeConfig>();
if (configSection == null)
{
return;
}
var ipAddressesOfNode = Dns.GetHostEntry(configSection.Node).AddressList.Select(ip => ip.ToString()).ToArray();
var ipAddressesOfHost = Dns.GetHostEntry(Environment.MachineName).AddressList.Select(ip => ip.ToString()).ToArray();
if (ipAddressesOfHost.Any(ipAddressesOfNode.Contains))
{
//Valid DNS Name
}
最後に、次のオプションで終了します。
1.失敗したアプローチ: IHandleProfile で MasterNodeConfig の Node 値を変更します。このアプローチは気に入りましたが、欠点はほとんどありません。MasterNodeConfig は IsReadonly() のデフォルトの動作をオーバーライドせず、エラーをスローするため、機能しません。統合プロファイルを使用する場合、インストール中に Worker & Distributor キューは作成されません。
internal class MasterNodeConfigSetup : IHandleProfile<Master>
{
public void ProfileActivated()
{
var configSection = Configure.GetConfigSection<MasterNodeConfig>();
configSection.Node = Environment.MachineName;
}
}
上記のコードによって作成されたランタイム エラーを回避するためのハックがあります。しかし、他のキューの作成を手動で行う場合は、これを使用できます。
var field = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(configSection, false);
configSection.Node = Environment.MachineName;
}
2.worker と master の 2 つの異なる Config ファイルを保持し、パッケージ化します。多くの作業が実行可能に見えます。
3. マスター コンポーネントの展開中に MasterNodeConfig を削除します。
私はNSBに反対ではなく、NSBが大好きです。私はフラストレーションを表明しているだけで、理由を知りたいと思っていました。MasterNode 値を追加する理由と、解決する代わりに Environemnt で検証するだけの理由。
私はあなたからの提案を受け入れることに非常にオープンです。