跳到主要内容
版本:3.0.0

ID 生成器(Aegis.IdGenerator)

Aegis.IdGenerator 是 Aegis 中统一的编号生成组件。它同时覆盖两类能力:

  • 雪花 ID:生成全局唯一的 long
  • 模板 ID:按业务模板生成带日期、流水号、前缀的字符串编号

组件概览

字段说明
组件名称ID 生成器
真实类库Aegis.IdGenerator
组件定位雪花 ID 与模板编号生成
引入方式安装 NuGet,并在 Component.deps.json 中启用对应声明
组件声明IdGeneratorIdGenerator.SnowflakeIdIdGenerator.TemplateId
配置节点IdGenerator
核心能力IIdGeneratorITemplateIdGeneratorIIdTemplateManager

先记住三种装配方式的区别

组件声明会注册什么适合场景
IdGenerator同时注册雪花 ID 和模板 ID默认推荐
IdGenerator.SnowflakeId只注册 IIdGenerator只需要雪花 ID
IdGenerator.TemplateId只注册模板生成与模板管理只需要业务编号

如果你没有特别要拆开的理由,直接使用 IdGenerator 最稳。

最小可运行路径

第一步:启用 IdGenerator

默认推荐直接启用总入口:

{
"Components": {
"Services": [
"IdGenerator"
]
}
}

如果你只想要雪花 ID,也可以只启用:

{
"Components": {
"Services": [
"IdGenerator.SnowflakeId"
]
}
}

第二步:准备雪花配置

{
"IdGenerator": {
"WorkerId": 2,
"WorkerIdLength": 5,
"IndexLength": 8
}
}

第三步:在业务类里注入

public class OrderService
{
private readonly IIdGenerator _idGenerator;

public OrderService(IIdGenerator idGenerator)
{
_idGenerator = idGenerator;
}
}

雪花 ID 怎么用

获取单个 ID

var id = _idGenerator.NextId();

什么时候最适合用雪花 ID

适合场景:

  • 主键需要是数字类型
  • 只关心唯一性,不关心业务含义
  • 需要在多节点下快速生成唯一编号

这组雪花配置分别控制什么

配置项作用
WorkerId当前实例的工作节点编号
WorkerIdLengthWorkerId 所占位数
IndexLength同一时间窗口内流水号位数
WorkerIdProviderWorkerId 提供器类型名
StartTimeStamp雪花算法起始时间

使用雪花 ID 时最重要的一条规则

多实例部署时,WorkerId 不能重复。
如果多个实例用了同一个 WorkerId,雪花 ID 的唯一性就没有保障。

模板 ID 在当前组件里处于什么位置

启用 IdGeneratorIdGenerator.TemplateId 后,会注册:

  • ITemplateIdGenerator
  • IIdTemplateManager

但模板 ID 只是“生成规则”和“模板管理”层。
如果你希望模板流水号在多实例间共享,通常还要继续接 Redis ID 生成提供程序(Aegis.IdGenerator.Provider.Redis)

模板能力最常见的三个入口

注册模板提供者

services.AddIdTemplateProvider<TemplateProvider>();

获取模板 ID

var id = _templateIdGenerator.GetId("A1");
var ids = _templateIdGenerator.GetIds("A1", 30);

管理模板

_idTemplateManager.Add(new IdTemplate
{
Key = "A1",
CanReturn = true,
DateReset = true,
FormatString = "Test{Date}{SerialNum}",
SerialNumLength = 6,
PaddingChar = '0'
});

_idTemplateManager.Remove("A1");

IdTemplate 常用字段

字段作用
Key模板键
FormatString编号格式,如 Test{Date}{SerialNum}
SerialNumLength流水号长度
PaddingChar流水号填充字符
DateReset是否按日期重置流水
CanReturn是否允许归还编号
MinSerialNum最小流水号
MaxSerialNum最大流水号
RecoveryTime归还时间窗口

归还和确认编号

_templateIdGenerator.ReleaseId("A1", id);
_templateIdGenerator.ConfirmId("A1", id);
_templateIdGenerator.ConfirmIds("A1", ids);

什么时候要接 Redis 容器

只要进入以下场景,就建议把模板流水号切到 Redis:

  • 多实例部署
  • 模板编号要跨实例共享
  • 需要归还和重用编号
  • 不希望单机重启后序号行为失控
services.AddRedisSource<AegisRedisSource>(
ConfigManager.Get<RedisOptions>("Redis"));

services.AddIdRedisContainer<AegisRedisSource>();
services.AddIdTemplateProvider<TemplateProvider>();

接入完成后怎么确认成功

你至少应该确认这些点:

  • Component.deps.json 已包含正确的 IdGenerator 组件声明
  • IdGenerator 配置节能被正确读取
  • 容器里可以注入 IIdGenerator
  • 调用 NextId() 能持续返回不重复的 long
  • 如果启用了模板能力,容器里也可以注入 ITemplateIdGenerator

常见问题

为什么只能注入到 IIdGenerator,但拿不到模板能力

通常是只启用了 IdGenerator.SnowflakeId,没有启用 IdGeneratorIdGenerator.TemplateId

为什么雪花 ID 会冲突

最常见原因是多实例用了同一个 WorkerId

为什么模板能力已经打开,但一生成就报错

优先检查:

  1. 是否真的注册了 IIdTemplateProvider
  2. 模板 Key 是否存在
  3. 如果走分布式流水号,是否继续接了 Redis 容器

下一步看哪里