針對前端 Server 需將 Command 分派至多個後端 App Server(如 Order、Warehouse)的分散式場景,本文展示基於 MSMQ 的 CommandBus 實作,支援:

圖 1 三層架構:前端 → CommandBus (MSMQ) → 多 App Server
// 非同步
var cmd = new ACommand { Tag = "aaa" };
var bus = new CommandBusDistributer<ACommand, ACommandResult>();
bus.ResultCatched += (sender, result) => { /* 處理回應 */ };
bus.SendRequest(cmd);
// 同步阻塞
var result = bus.WaitResponse(); // 內部以 EventWaitHandle 等待
<CommandBusSetting>
<AutoCreateIfNotExists>true</AutoCreateIfNotExists>
<WebSessionSupport>true</WebSessionSupport>
<CommandQueue>PC-20130606HCVP\private$\Commands_{0}</CommandQueue>
<ResponseQueue>PC-20130606HCVP\private$\CommandResponses</ResponseQueue>
<NetworkLocation>\\PC-20130606HCVP\network</NetworkLocation>
</CommandBusSetting>
[QueueName("ACommand")] // 可選,預設類名為佇列名
public class ACommand : BaseCommand {
public string Tag { get; set; }
}

圖 2 CommandHandlerHost 專案結構
// Host 1
static void Main() {
Thread.Sleep(2000);
var listener = new CommandHandlerListener();
listener.AddHandler(new TestCommandHandlers());
listener.AddHandler(new Test2CommandHandlers());
listener.Start();
Console.ReadKey();
}
// Handler 實作
public class TestCommandHandlers :
ICommandHandler<ACommand, ACommandResult>,
ICommandHandler<BCommand, BCommandResult> {
public ACommandResult Handler(ACommand cmd, ISessionContext session) { ... }
public BCommandResult Handler(BCommand cmd, ISessionContext session) {
if (session != null) {
var val = session.GetWebSession("key1"); // 讀取前端 Session
}
...
}
}

圖 3 吞吐量與延遲測試結果
已整合至 A2D Framework,可直接引用 NuGet 套件使用。
作者:玄魂
出處:https://www.cnblogs.com/xuanhun/