










https://jdaniel1987.github.io/EventDrivenArchitecture
这是一篇基于你提供的网页内容整理的博客文章。为了便于读者理解,我优化了排版结构,并保留了代码示例和关键图表描述。
作者:Jaime Daniel Delgado Ortega
发布时间:2024年12月4日
阅读时间:约 5 分钟
事件驱动架构 (Event-Driven Architecture, EDA) 是一种软件设计模式,它使用“事件”作为核心通信手段,从而解耦生产者和消费者。
在这篇文章中,我们将探讨如何使用 Azure Service Bus 和 MassTransit 在 .NET 中实现事件驱动系统。虽然我们将重点放在 Azure Service Bus 上,但这些原则同样适用于 RabbitMQ、Kafka 或 Amazon SQS 等其他消息代理。
在深入代码之前,我们需要理解 EDA 的四个基本组成部分:
架构图解:
想象一个中心化的 消息代理 (Message Broker)。
- 左侧是 事件生产者 (Event Producers),它们将事件发送进代理。
- 右侧是 事件消费者 (Event Consumers),它们从代理中接收并处理事件。
- 生产者和消费者互不直接通信,完全通过代理进行解耦。
在 .NET 生态中,常见的选择包括:
安装必要的 NuGet 包:
dotnet add package MassTransit
dotnet add package MassTransit.Azure.ServiceBus.Core
这是发布事件的核心代码。我们配置 MassTransit 连接到 Azure Service Bus 并发布一个 OrderPlaced 事件。
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureServices((context, services) =>
{
services.AddMassTransit(x =>
{
x.UsingAzureServiceBus((context, cfg) =>
{
// 替换为你的 Azure Service Bus 连接字符串
cfg.Host("<your-azure-service-bus-connection-string>");
});
});
services.AddMassTransitHostedService();
});
var host = builder.Build();
using var scope = host.Services.CreateScope();
var bus = scope.ServiceProvider.GetRequiredService<IBus>();
// 发布事件
await bus.Publish(new OrderPlaced {
OrderId = Guid.NewGuid(),
Timestamp = DateTime.UtcNow
});
消费者负责监听特定的队列并处理逻辑。
public class OrderPlacedConsumer : IConsumer<OrderPlaced>
{
public async Task Consume(ConsumeContext<OrderPlaced> context)
{
Console.WriteLine($"Order received: {context.Message.OrderId} at {context.Message.Timestamp}");
// 在此处添加你的业务逻辑
}
}
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureServices((context, services) =>
{
services.AddMassTransit(x =>
{
x.AddConsumer<OrderPlacedConsumer>();
x.UsingAzureServiceBus((context, cfg) =>
{
cfg.Host("<your-azure-service-bus-connection-string>");
cfg.ReceiveEndpoint("order-queue", e =>
{
e.ConfigureConsumer<OrderPlacedConsumer>(context);
});
});
});
services.AddMassTransitHostedService();
});
await builder.Build().RunAsync();
生产者和消费者需要共享相同的事件定义(通常放在共享库中)。
public record OrderPlaced
{
public Guid OrderId { get; init; }
public DateTime Timestamp { get; init; }
}
为了确保系统的弹性,必须有效处理瞬时错误。
使用 Polly 实现重试的代码示例:
using Azure.Messaging.ServiceBus;
using Polly;
using Polly.Retry;
using System;
using System.Threading.Tasks;
class Program
{
private const string ConnectionString = "<Your-Service-Bus-Connection-String>";
private const string QueueName = "example-queue";
static async Task Main(string[] args)
{
var client = new ServiceBusClient(ConnectionString);
var sender = client.CreateSender(QueueName);
// 定义重试策略
var retryPolicy = Policy
.Handle<ServiceBusException>(ex => ex.IsTransient)
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetry: (exception, duration, attempt, context) =>
{
Console.WriteLine($"Retrying due to: {exception.Message}. Attempt: {attempt}");
});
var message = new ServiceBusMessage("Hello, Service Bus!");
try
{
await retryPolicy.ExecuteAsync(async () =>
{
Console.WriteLine("Sending message...");
await sender.SendMessageAsync(message);
Console.WriteLine("Message sent successfully!");
});
}
catch (Exception ex)
{
Console.WriteLine($"Failed to send message after retries. Exception: {ex.Message}");
}
finally
{
await sender.DisposeAsync();
await client.DisposeAsync();
}
}
}
不同的消息代理适用于不同的场景。以下是主要特性的对比:
| 特性 | Azure Service Bus | RabbitMQ | Kafka | Amazon SQS |
|---|---|---|---|---|
| 类型 | 消息队列 | 消息队列 | 事件日志 | 消息队列 |
| 持久性 | 高 | 可选 | 高 | 高 |
| 可扩展性 | 高 | 中等 | 非常高 | 高 |
| 排序 | 保证 | 可选 | 保证 | 可选 |
| 适用场景 | 企业级应用 | 轻量级系统 | 流分析 | 云原生系统 |
总结:Azure Service Bus 非常适合需要死信处理、会话和事务等高级功能的企业级系统。
在生产环境中,你需要知道系统是否健康。可以使用以下工具来跟踪事件处理指标:
事件驱动架构是一种灵活的模式,能显著增强现代应用程序的解耦性、可扩展性和弹性。通过利用 Azure Service Bus 和 MassTransit 等工具,你可以快速构建健壮的分布式系统。
根据你的项目需求,也可以考虑 RabbitMQ、Kafka 或 Amazon SQS 等其他选择。
本文基于 CC BY 4.0 许可发布。
出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。