使用NServiceBus开发分布式应用
前言
NServiceBus是.Net平台下的开源的消息服务框架,已经支持.Net Core。目前稳定版本7.1。企业开发需要购买License,开发者可在线下载开发者License。
官方网站:https://particular.net/
官方示例:https://docs.particular.net/get-started/
NServiceBus入门
如图所示,项目一共包括4个端点(Endpoint),也就是四个单独的项目,端点是NServiceBus中的核心概念,发送消息和事件发布订阅的基础都是Endpoint。这个项目中包括发送消息和事件的发布订阅。
ClientUI
class Program
{
private static ILog log = LogManager.GetLogger<Program>();
static void Main(string[] args)
{
MainAsync().GetAwaiter().GetResult();
}
static async Task RunAsync(IEndpointInstance endpointInstance)
{
log.Info("Press 'P' to place an order,press 'Q' to quit");
while (true)
{
var key = Console.ReadKey();
Console.WriteLine();
switch (key.Key)
{
case ConsoleKey.P:
{
var command = new PlaceOrder
{
OrderId = Guid.NewGuid().ToString()
};
log.Info($"Sending PlaceOrder with OrderId:{command.OrderId}");
//发送到Sales端点
await endpointInstance.Send("Sales",command).ConfigureAwait(false);
break;
}
case ConsoleKey.Q:
return;
default:
log.Info("Please try again");
break;
}
}
}
static async Task MainAsync()
{
Console.Title = "Client-UI";
var config = new EndpointConfiguration("ClientUI");//设置端点名称
config.UseTransport<LearningTransport>(); //设置消息管道模式,LearningTransport仅仅用来学习,生产慎用
config.UsePersistence<LearningPersistence>();//持久化
var endpointInstance =await Endpoint.Start(config).ConfigureAwait(false);
await RunAsync(endpointInstance).ConfigureAwait(false); //RunAsync返回的是Task,所以这里使用ConfigureAwait()
await endpointInstance.Stop().ConfigureAwait(false);
}
}
Sales
class Program
{
static async Task Main(string[] args)
{
Console.Title = "Sales";
var config = new EndpointConfiguration("Sales");
config.UseTransport<LearningTransport>();
config.UsePersistence<LearningPersistence>();
var endpointInstance = await Endpoint.Start(config).ConfigureAwait(false);
Console.WriteLine("Press Enter to quit...");
Console.ReadLine();
await endpointInstance.Stop().ConfigureAwait(false);
}
}
public class PlaceOrderHandler:IHandleMessages<PlaceOrder>
{
private static ILog log = LogManager.GetLogger<PlaceOrderHandler>();
public Task Handle(PlaceOrder message, IMessageHandlerContext context)
{
//接受端点消息
log.Info($"Received PlaceOrder ,OrderId:{message.OrderId}");
//发布OrderPlaced事件
var order=new OrderPlaced();
order.OrderId = message.OrderId;
return context.Publish(order);
}
}
Billing
static async Task Main(string[] args)
{
Console.Title = "Sales";
var config = new EndpointConfiguration("Billing");
config.UseTransport<LearningTransport>();
config.UsePersistence<LearningPersistence>();
var endpointInstance = await Endpoint.Start(config).ConfigureAwait(false);
Console.WriteLine("Press Enter to quit...");
Console.ReadLine();
await endpointInstance.Stop().ConfigureAwait(false);
}
public class OrderPlacedHandler:IHandleMessages<OrderPlaced>
{
private static ILog log = LogManager.GetLogger<OrderPlacedHandler>();
public Task Handle(OrderPlaced message, IMessageHandlerContext context)
{
//订阅OrderPlaced事件
log.Info($"Received OrderPlaced,OrderId {message.OrderId} - Charging credit card");
//发布OrderBilled事件
var order=new OrderBilled();
order.OrderId = message.OrderId;
return context.Publish(order);
}
}
Shipping
static async Task Main(string[] args)
{
Console.Title = "Sales";
var config = new EndpointConfiguration("Shipping");
config.UseTransport<LearningTransport>();
config.UsePersistence<LearningPersistence>();
var endpointInstance = await Endpoint.Start(config).ConfigureAwait(false);
Console.WriteLine("Press Enter to quit...");
Console.ReadLine();
await endpointInstance.Stop().ConfigureAwait(false);
}
public class OrderBilledHandler:IHandleMessages<OrderBilled>
{
private static ILog log = LogManager.GetLogger<OrderBilledHandler>();
//处理OrderBilled订阅事件
public Task Handle(OrderBilled message, IMessageHandlerContext context)
{
log.Info($"Received OrderBilled,OrderId={message.OrderId} Should we ship now?");
return Task.CompletedTask;
}
}
public class OrderPlacedHandler:IHandleMessages<OrderPlaced>
{
private static ILog log = LogManager.GetLogger<OrderPlacedHandler>();
//处理OrderPlaced订阅事件
public Task Handle(OrderPlaced message, IMessageHandlerContext context)
{
log.Info($"Received OrderPlaced,OrderId={message.OrderId} Should we ship now?");
return Task.CompletedTask;
}
}
运行结果
总结
NServiceBus的核心是在端点之间通信,通信的实体需要实现ICommand接口,通信的事件需要实现IEvent事件,NServiceBus会扫描实现这两个接口的类。每个端点之间的关键配置就是EndpointConfiguration。
作者:sword-successful
出处:https://www.cnblogs.com/sword-successful/p/11716408.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
博客地址: | http://www.cnblogs.com/sword-successful/ |
博客版权: | 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。 如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。 |
分类:
【框架】NServiceBus
标签:
.Net Core
, Asp.net Core
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构