golang分布式生成超短唯一非连续URL友好ID插件库shortid的使用
Golang分布式生成超短唯一非连续URL友好ID插件库shortid的使用
shortid是一个用于生成短小、完全唯一、非连续且默认URL友好的ID的Go语言库,每秒可生成数十万个ID,并保证在2050年前不会出现重复。
快速开始
最简单的使用方式:
fmt.Printf(shortid.Generate())
fmt.Printf(shortid.Generate())
推荐的方式是为特定worker初始化并重用生成器:
// 创建新的生成器实例
// 参数:worker编号(0-31),字母表,随机种子
sid, err := shortid.New(1, shortid.DefaultABC, 2342)
// 使用方式1:直接使用生成器实例
fmt.Printf(sid.Generate())
fmt.Printf(sid.Generate())
// 使用方式2:设置为默认生成器
shortid.SetDefault(sid)
// 然后使用全局函数生成
fmt.Printf(shortid.Generate())
fmt.Printf(shortid.Generate())
ID长度特性
- 标准ID长度为9个字符(当以每秒1个ID的速度生成时)
- 偶尔会达到11个字符(每秒数千个ID时)
- 极少数情况下会更长(在持续高并发生成时)
生命周期保证
该库保证:
- 34年内不会产生重复ID(2016-2050)
- 支持最多32个worker同时生成唯一序列
- 要求应用重启间隔大于1毫秒
完整示例
package main
import (
"fmt"
"github.com/teris-io/shortid"
)
func main() {
// 初始化生成器
sid, err := shortid.New(1, shortid.DefaultABC, 2342)
if err != nil {
panic(err)
}
// 生成10个ID
for i := 0; i < 10; i++ {
id := sid.Generate()
fmt.Printf("Generated ID: %s\n", id)
}
// 设置为默认生成器
shortid.SetDefault(sid)
// 使用全局函数生成
for i := 0; i < 5; i++ {
id := shortid.Generate()
fmt.Printf("Default generated ID: %s\n", id)
}
}
实现特点
- 并发安全
- 不需要年度版本/epoch重置
- 在1ms速率下ID大小稳定
- 保证无冲突
- 支持32个worker(原node.js版支持16个)
算法细节
每个ID包含三部分信息:
- 从epoch开始的毫秒数(前8个字符,epoch: 2016/1/1)
- worker ID(第9个字符)
- 毫秒内的运行计数器(仅在需要时,占用剩余字符)
随机性:
- worker和毫秒数据:1/2随机性
- 计数器:无随机性
许可证
Copyright (c) 2016. Oleg Sklyar and teris.io. MIT license applies. All rights reserved.
更多关于golang分布式生成超短唯一非连续URL友好ID插件库shortid的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang分布式生成超短唯一非连续URL友好ID插件库shortid的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang分布式生成超短唯一非连续URL友好ID插件库shortid使用指南
shortid是一个用于生成分布式环境下超短、唯一、非连续且URL友好的ID的Go语言库。它特别适合需要生成短链接ID、订单号等场景。
安装
go get github.com/teris-io/shortid
基本用法
1. 生成ID
package main
import (
"fmt"
"github.com/teris-io/shortid"
)
func main() {
// 生成一个ID
id, err := shortid.Generate()
if err != nil {
panic(err)
}
fmt.Println("Generated ID:", id) // 输出类似: "g6XxXxXx"
}
2. 自定义配置
func customConfig() {
// 自定义配置
sid, err := shortid.New(1, shortid.DefaultABC, 2342)
if err != nil {
panic(err)
}
// 使用自定义配置生成ID
id := sid.MustGenerate()
fmt.Println("Custom ID:", id)
}
高级特性
1. 分布式支持
shortid支持分布式环境,通过为每个worker设置不同的worker编号来避免冲突:
func distributedUsage() {
// worker编号从0开始,集群中每个实例应有唯一编号
worker := 2 // 假设这是第3个worker
sid, err := shortid.New(worker, shortid.DefaultABC, 2342)
if err != nil {
panic(err)
}
for i := 0; i < 5; i++ {
fmt.Println("Distributed ID:", sid.MustGenerate())
}
}
2. 自定义字符集
func customAlphabet() {
// 自定义字符集(仅包含数字和大写字母)
customABC := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
sid, err := shortid.New(1, customABC, 2342)
if err != nil {
panic(err)
}
fmt.Println("Custom alphabet ID:", sid.MustGenerate())
}
3. 设置随机种子
func withSeed() {
// 设置随机种子以确保可重现结果(仅用于测试)
sid, err := shortid.New(1, shortid.DefaultABC, 1234) // 固定seed
if err != nil {
panic(err)
}
// 每次运行都会生成相同的ID序列
fmt.Println("ID with fixed seed 1:", sid.MustGenerate())
fmt.Println("ID with fixed seed 2:", sid.MustGenerate())
}
性能考虑
shortid设计为高性能ID生成器,但如果你在极高并发环境下使用,可以考虑以下优化:
func concurrentUsage() {
sid := shortid.MustNew(1, shortid.DefaultABC, 2342)
// 使用channel批量生成ID
ids := make(chan string, 100)
go func() {
for i := 0; i < 100; i++ {
ids <- sid.MustGenerate()
}
close(ids)
}()
for id := range ids {
fmt.Println(id)
}
}
实际应用示例
短链接服务
package main
import (
"fmt"
"net/http"
"github.com/teris-io/shortid"
)
var sid = shortid.MustNew(1, shortid.DefaultABC, 2342)
func main() {
urlStore := make(map[string]string)
http.HandleFunc("/shorten", func(w http.ResponseWriter, r *http.Request) {
longURL := r.URL.Query().Get("url")
if longURL == "" {
http.Error(w, "URL parameter is required", http.StatusBadRequest)
return
}
shortID := sid.MustGenerate()
urlStore[shortID] = longURL
fmt.Fprintf(w, "Short URL: http://localhost:8080/%s", shortID)
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
shortID := r.URL.Path[1:]
if longURL, ok := urlStore[shortID]; ok {
http.Redirect(w, r, longURL, http.StatusFound)
} else {
http.NotFound(w, r)
}
})
fmt.Println("Server started at :8080")
http.ListenAndServe(":8080", nil)
}
注意事项
- 唯一性保证:确保在分布式环境中每个worker有唯一的编号
- 字符集选择:默认字符集是URL友好的,修改时需确保仍符合URL规范
- ID长度:生成的ID长度会随着生成数量的增加而自动增长
- 安全性:生成的ID不是加密安全的,不应用作安全令牌
shortid是一个简单高效的解决方案,适合需要短ID的大多数场景。对于更高要求的环境,也可以考虑其他方案如ULID或UUID。