ID 生成器(Aegis.IdGenerator)
Aegis.IdGenerator 是 Aegis 中统一的编号生成组件。它同时覆盖两类能力:
- 雪花 ID:生成全局唯一的
long - 模板 ID:按业务模板生成带日期、流水号、前缀的字符串编号
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | ID 生成器 |
| 真实类库 | Aegis.IdGenerator |
| 组件定位 | 雪花 ID 与模板编号生成 |
| 引入方式 | 安装 NuGet,并在 Component.deps.json 中启用对应声明 |
| 组件声明 | IdGenerator、IdGenerator.SnowflakeId、IdGenerator.TemplateId |
| 配置节点 | IdGenerator |
| 核心能力 | IIdGenerator、ITemplateIdGenerator、IIdTemplateManager |
先记住三种装配方式的区别
| 组件声明 | 会注册什么 | 适合场景 |
|---|---|---|
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 | 当前实例的工作节点编号 |
WorkerIdLength | WorkerId 所占位数 |
IndexLength | 同一时间窗口内流水号位数 |
WorkerIdProvider | WorkerId 提供器类型名 |
StartTimeStamp | 雪花算法起始时间 |
使用雪花 ID 时最重要的一条规则
多实例部署时,WorkerId 不能重复。
如果多个实例用了同一个 WorkerId,雪花 ID 的唯一性就没有保障。
模板 ID 在当前组件里处于什么位置
启用 IdGenerator 或 IdGenerator.TemplateId 后,会注册:
ITemplateIdGeneratorIIdTemplateManager
但模板 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,没有启用 IdGenerator 或 IdGenerator.TemplateId。
为什么雪花 ID 会冲突
最常见原因是多实例用了同一个 WorkerId。
为什么模板能力已经打开,但一生成就报错
优先检查:
- 是否真的注册了
IIdTemplateProvider - 模板
Key是否存在 - 如果走分布式流水号,是否继续接了 Redis 容器