Documentation
¶
Overview ¶
Package uidgen 提供分布式唯一 ID 生成器.
推荐使用 Snowflake(全局单例 + 极简 API):
uidgen.InitSnowflake(7) // 一次性初始化, machineID ∈ [0, 1023] id := uidgen.SnowflakeID() // int64, 不返错, auto-init 兜底 uidgen.ExtractSnowflakeTime(id) // epoch = 2026-01-01 uidgen.ExtractSnowflakeMachineID(id) uidgen.ExtractSnowflakeSequence(id)
Extract 函数(epoch = 2024-01-01)用于从旧式 ID 中提取元数据:
uidgen.ExtractTime(id) uidgen.ExtractWorkerID(id) uidgen.ExtractSequence(id)
UUID 系列(与 Snowflake 无关)见 uuid.go.
ULID 系列(26 字符,字典序 == 时间序)见 ulid.go——面向「文本主键 + 按 ID 做时间序 range scan」的场景:
id := uidgen.ULID() // 26 字符,同毫秒内严格递增 uidgen.ULIDFromTime(t) // 指定时间戳(按业务时间回填) ts, entropy, err := uidgen.ParseULID(id) // 解回时间戳与 80 bit 熵
crypto/rand 随机串生成(标识符/密钥面):与 Snowflake(可预测、仅作 ID)分居—— 密钥、一次性凭据、高熵标识符必须走本文件。
Index ¶
- Variables
- func ExtractSequence(id int64) int64
- func ExtractSnowflakeMachineID(id int64) int64
- func ExtractSnowflakeSequence(id int64) int64
- func ExtractSnowflakeTime(id int64) time.Time
- func ExtractTime(id int64) time.Time
- func ExtractWorkerID(id int64) int64
- func InitSnowflake(machineID int64) error
- func InitSnowflakeFromEnv() error
- func ParseULID(s string) (time.Time, []byte, error)
- func RandomHex(nBytes int) string
- func RandomString(alphabet string, n int) string
- func ShortUUID() string
- func ShortUUIDToUpper() string
- func SnowflakeID() int64
- func SnowflakeMachineID() int64
- func ULID() string
- func ULIDFromTime(t time.Time) string
- func UUID() string
- func UUIDToUpper() string
- func UUIDWithHyphen() string
- type Snowflake
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidULID = errors.New("uidgen: invalid ULID")
ErrInvalidULID 表示字符串不是合法 ULID:长度不对、含非法字符, 或超出 128 bit 范围(首字符取值大于 '7')。
调用方用 errors.Is(err, uidgen.ErrInvalidULID) 判定;具体原因在错误消息里。
Functions ¶
func ExtractSnowflakeMachineID ¶
ExtractSnowflakeMachineID 从 Snowflake ID 中提取 machineID.
func ExtractSnowflakeSequence ¶
ExtractSnowflakeSequence 从 Snowflake ID 中提取 sequence.
func ExtractSnowflakeTime ¶
ExtractSnowflakeTime 从 Snowflake ID 中提取生成时间. 注意:与 ExtractTime 不可混用——epoch 不同(2026 vs 2024).
func InitSnowflake ¶
InitSnowflake 初始化全局 Snowflake singleton. machineID 必须在 [0, 1023] 范围. 多次调用:第一次生效,后续返错(防止误用).
并发安全:CAS(nil -> s) 失败表示已初始化,Load() 拿到的是上次成功的实例.
func InitSnowflakeFromEnv ¶
func InitSnowflakeFromEnv() error
InitSnowflakeFromEnv 从 MACHINE_ID env 读 machineID,解析失败兜底 0. 单进程 dev / 测试默认 0 够用;生产必须显式注入(e.g. docker-compose 配 0/1/2).
func ParseULID ¶ added in v0.3.0
ParseULID 解析 ULID,返回它的毫秒时间戳与 80 bit 熵(10 字节)。
大小写不敏感(ULID 规范如此)。长度不对、含非法字符、或超出 128 bit (首字符取值大于 '7')时返回包装了 ErrInvalidULID 的错误。
func RandomHex ¶
RandomHex n 字节 crypto/rand 随机数的十六进制串(2n 字符)。n<=0 返回空串。 适用:对象 ID、webhook secret 等高熵标识符。
func RandomString ¶
RandomString 从 alphabet 均匀采样 n 个字符(拒绝采样消模偏差,无 mod 偏置)。 alphabet 为空时 panic。适用:带自定义字符集的短 ID/令牌。
func SnowflakeID ¶
func SnowflakeID() int64
SnowflakeID 拿下一个 int64 ID. 未 InitSnowflake 时自动以 machineID=0 初始化.
并发说明:auto-init 路径在多 goroutine 同时首次调用时,CAS 失败的 goroutine 会回退到 Load() 读已 init 的实例,保证不会 nil deref.
时钟回拨:阻塞等直到时间追平,不返错. 业务层应监控回拨时长,超过阈值告警.
func SnowflakeMachineID ¶
func SnowflakeMachineID() int64
SnowflakeMachineID 返当前 init 用的 machine ID,未初始化返 -1,测试用.
func ULID ¶ added in v0.3.0
func ULID() string
ULID 返回 26 字符的 ULID(Universally Unique Lexicographically Sortable Identifier)。
结构 = 48 bit 毫秒时间戳(Unix 纪元)+ 80 bit 熵,Crockford Base32 编码。 适用于「文本主键 + 按 ID 做时间序 range scan」这一类需求: Snowflake 是 int64(不能直接当文本主键),UUID 是随机串(字典序与时间无关)。
同一毫秒内进程内**严格单调**:熵逐个递增,80 bit 熵用尽则进位到下一毫秒。 时钟回拨时冻结在上一次的毫秒继续递增熵,保证不会出现更小的 ID。
零第三方依赖:crypto/rand + 标准库。
func ULIDFromTime ¶ added in v0.3.0
ULIDFromTime 用指定时间戳生成 ULID,便于按业务时间回填 ID。
时间戳取 t 的 Unix 毫秒;熵为随机值。**不参与 ULID() 的进程内单调序列** ——回填的业务时间可能早于当前时间,混进单调序列会破坏它的单调性。 同一 t 多次调用得到的 ULID 彼此无序,需要有序时请用 ULID()。
t 超出 48 bit 毫秒时间戳范围(Unix 纪元之前,或公元 10889 年之后)时 panic: 这种时间戳编不出合法 ULID,静默截断会得到一个「时间不对但看着正常」的 ID。
Types ¶
type Snowflake ¶
type Snowflake struct {
// contains filtered or unexported fields
}
Snowflake 是 singleton 模式的 Snowflake ID 生成器.
Bit 布局(bit 63 → 0):
[1 sign | 41 ts | 10 machine | 12 sequence]
= ~69 years × 1024 machines × 4096 IDs/ms per machine.
区别于旧式 ID 生成:
- Singleton 模式,业务侧直接调 SnowflakeID() 拿下一个 int64 ID.
- 时钟回拨持锁忙等,不返错.
- API 极简:InitSnowflake + SnowflakeID,不暴露 mu / sequence / lastTS.
并发模型:
- InitSnowflake 用 atomic.Pointer CAS 保证 "只 init 一次" + "成功后立刻可见".
- SnowflakeID() auto-init 路径在 CAS 失败时回退到 Load(),避免 nil deref.
- next() 持单 mu 串行:临界区短(同 ms 仅几次算术,跨 ms 持锁等下 ms 最坏 1ms).
Reference: https://github.com/twitter-archive/snowflake (Twitter, 2010)