CAP 是一个在分布式系统(SOA、MicroService)中实现最终一致性的库,它具有轻量级、易使用、高性能等特点。
CAP 是在一个 ASP.NET Core 项目中使用的库,当然他可以用于 ASP.NET Core On .NET Framework 中。
你可以把 CAP 看成是一个 EventBus,因为它具有 EventBus 的所有功能,并且CAP提供了更加简化的方式来处理 EventBus 中的发布和订阅。
CAP 具有消息持久化的功能,当你的服务进行重启或者宕机时它可以保证消息的可靠性。CAP提供了基于Microsoft DI 的 Producer Service 服务,它可以和你的业务服务进行无缝结合,并且支持强一致性的事务。
这是CAP集在ASP.NET Core 微服务架构中的一个示意图:
图中实线部分代表用户代码,虚线部分代表CAP内部实现。
你可以运行以下下命令在你的项目中安装 CAP。
如果你的消息队列使用的是 Kafka 的话,你可以:
PM> Install-Package DotNetCore.CAP.Kafka -Pre
如果你的消息队列使用的是 RabbitMQ 的话,你可以:
PM> Install-Package DotNetCore.CAP.RabbitMQ -Pre
CAP 默认提供了 Entity Framwork 作为数据库存储:
PM> Install-Package DotNetCore.CAP.EntityFrameworkCore -Pre
首先配置CAP到 Startup.cs 文件中,如下:
public void ConfigureServices(IServiceCollection services)
{
......
services.AddDbContext<AppDbContext>();
services.AddCap()
.AddEntityFrameworkStores<AppDbContext>()
.AddKafka(x => x.Servers = "localhost:9092");
}
public void Configure(IApplicationBuilder app)
{
.....
app.UseCap();
}
在 Controller 中注入 ICapProducerService
然后使用 ICapProducerService
进行消息发送
public class PublishController : Controller
{
private readonly ICapProducerService _producer;
public PublishController(ICapProducerService producer)
{
_producer = producer;
}
[Route("~/checkAccount")]
public async Task<IActionResult> PublishMessage()
{
//指定发送的消息头和内容
await _producer.SendAsync("xxx.services.account.check", new Person { Name = "Foo", Age = 11 });
return Ok();
}
}
Action Method
在 Action 上添加 CapSubscribeAttribute 来订阅相关消息。
public class PublishController : Controller
{
private readonly ICapProducerService _producer;
public PublishController(ICapProducerService producer)
{
_producer = producer;
}
[NoAction]
[CapSubscribe("xxx.services.account.check")]
public async Task CheckReceivedMessage(Person person)
{
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
return Task.CompletedTask;
}
}
Service Method
如果你的订阅方法没有位于 Controller 中,则你订阅的类需要继承 ICapSubscribe
:
namespace xxx.Service
{
public interface ISubscriberService
{
public void CheckReceivedMessage(Person person);
}
public class SubscriberService: ISubscriberService, ICapSubscribe
{
[KafkaTopic("xxx.services.account.check")]
public void CheckReceivedMessage(Person person)
{
}
}
}
然后在 Startup.cs 中的 ConfigureServices()
中注入你的 ISubscriberService
类
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISubscriberService,SubscriberService>();
}
贡献的最简单的方法之一就是是参与讨论和讨论问题(issue)。你也可以通过提交的 Pull Request 代码变更作出贡献。
MIT