namespace Dpz.Core.MessageQueue.Models;
/// <summary>
/// Outbox 条目轻量 DTO,由 <see cref="Dpz.Core.MessageQueue.Abstractions.IMessageOutboxStore"/>
/// 的查询方法返回,供后台重试服务使用,避免传递完整的数据库实体。
/// </summary>
public record MessageOutboxEntry
{
/// <summary>
/// 初始化 Outbox 条目轻量 DTO。
/// </summary>
/// <param name="MessageId">消息唯一标识。</param>
/// <param name="Exchange">目标 Exchange 名称。</param>
/// <param name="RoutingKey">路由键。</param>
/// <param name="Payload">JSON 序列化的消息载荷。</param>
/// <param name="PublishAttempts">已尝试发布次数。</param>
/// <param name="ConsumeAttempts">已尝试消费次数。</param>
public MessageOutboxEntry(
string MessageId,
string Exchange,
string RoutingKey,
string Payload,
int PublishAttempts,
int ConsumeAttempts
)
{
this.MessageId = MessageId;
this.Exchange = Exchange;
this.RoutingKey = RoutingKey;
this.Payload = Payload;
this.PublishAttempts = PublishAttempts;
this.ConsumeAttempts = ConsumeAttempts;
}
/// <summary>
/// 消息唯一标识。
/// </summary>
public string MessageId { get; init; }
/// <summary>
/// 目标 Exchange 名称。
/// </summary>
public string Exchange { get; init; }
/// <summary>
/// 路由键。
/// </summary>
public string RoutingKey { get; init; }
/// <summary>
/// JSON 序列化的消息载荷。
/// </summary>
public string Payload { get; init; }
/// <summary>
/// 已尝试发布次数。
/// </summary>
public int PublishAttempts { get; init; }
/// <summary>
/// 已尝试消费次数。
/// </summary>
public int ConsumeAttempts { get; init; }
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个基于 C# record 类型定义的 消息发件箱条目轻量 DTO(Data Transfer Object)类。让我详细解释一下这个代码的作用和设计:
主要用途
这个类是为实现 Outbox Pattern(发件箱模式)而设计的数据传输对象。Outbox 模式是一种确保分布式系统中消息可靠发送的设计模式,通常用于:
- 事务性消息发送
- 确保数据库操作和消息发送的一致性
- 支持消息重试机制
类结构分析
1. Record 类型选择
public record MessageOutboxEntry
使用 record 而非 class 的优势:
- 不可变性:所有属性都是
init只读的 - 值语义:基于属性值进行相等性比较
- 简洁语法:自动生成构造函数、解构器等
2. 主构造函数
public MessageOutboxEntry(
string MessageId,
string Exchange,
string RoutingKey,
string Payload,
int PublishAttempts,
int ConsumeAttempts
)
定义了创建实例时必须提供的所有参数,确保对象创建时数据完整。
3. 核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
MessageId | string | 消息的全局唯一标识符,用于去重和追踪 |
Exchange | string | 消息队列的 Exchange 名称(如 RabbitMQ) |
RoutingKey | string | 消息路由键,决定消息发送到哪个队列 |
Payload | string | JSON 序列化后的消息内容 |
PublishAttempts | int | 记录消息发布失败重试次数 |
ConsumeAttempts | int | 记录消息消费失败重试次数 |
设计优势
1. 轻量化设计
- 只包含必要的字段,避免传递完整的数据库实体
- 减少内存占用和网络传输开销
2. 职责分离
- 专门为后台重试服务设计
- 与完整的数据库实体模型解耦
3. 重试机制支持
PublishAttempts和ConsumeAttempts支持失败重试逻辑- 可以根据重试次数实现退避策略
使用场景示例
// 后台服务获取待重试的消息
var failedMessages = await messageOutboxStore.GetFailedMessages();
foreach (var entry in failedMessages)
{
if (entry.PublishAttempts < maxRetries)
{
// 重新发布消息
await messagePublisher.PublishAsync(
entry.Exchange,
entry.RoutingKey,
entry.Payload
);
}
}
这个设计体现了现代 .NET 开发中的最佳实践:使用不可变的 record 类型、明确的职责划分、以及对分布式系统可靠性的考虑。
评论加载中...