package order import ( "fmt" "sync" "sync/atomic" "time" ) // 更安全的版本:带毫秒时间戳 type Generator struct { machineID int lastTime int64 // 上次时间(毫秒) sequence int64 mu sync.Mutex } func NewOrderNoGenerator(machineID int) *Generator { return &Generator{ machineID: machineID, lastTime: time.Now().UnixMilli(), sequence: 0, } } func (g *Generator) Generate() string { g.mu.Lock() defer g.mu.Unlock() currentTime := time.Now().UnixMilli() if currentTime == g.lastTime { g.sequence++ } else { g.sequence = 1 g.lastTime = currentTime } // 格式化时间,包含毫秒 t := time.UnixMilli(currentTime) // 格式:年月日时分秒 + 毫秒(3位) + 机器ID + 序列号 return fmt.Sprintf("%s%03d%02d%04d", t.Format("20060102150405"), // 14位 t.Nanosecond()/1e6, // 3位毫秒 g.machineID, // 2位 g.sequence, // 4位 ) } // GenerateString 生成字符串格式订单号 func (g *Generator) GenerateString(prefix string) string { // 调用无锁Generate获取ID id := g.Generate() // 格式化为字符串 return fmt.Sprintf("%s%s", prefix, id) } type GeneratorV3 struct { machineID int // 使用一个64位整数存储时间戳(42位)和序列号(22位) // 这样可以原子操作,不需要锁 counter uint64 } func NewOrderNoGeneratorV3(machineID int) *GeneratorV3 { return &GeneratorV3{ machineID: machineID, counter: 0, } } func (g *GeneratorV3) Generate() string { // 获取当前毫秒时间戳 now := uint64(time.Now().UnixMilli()) // 原子操作获取下一个ID var lastTime, seq uint64 for { old := atomic.LoadUint64(&g.counter) lastTime = old >> 22 // 高42位是时间戳 seq = old & 0x3FFFFF // 低22位是序列号 if now > lastTime { // 时间戳变化,重置序列号 seq = 0 lastTime = now } else if seq >= 0x3FFFFF { // 序列号达到最大值 // 等待下一毫秒 for now <= lastTime { time.Sleep(100 * time.Microsecond) now = uint64(time.Now().UnixMilli()) } seq = 0 lastTime = now } else { seq++ } newVal := (lastTime << 22) | (seq & 0x3FFFFF) if atomic.CompareAndSwapUint64(&g.counter, old, newVal) { break } } // 格式化输出 t := time.UnixMilli(int64(lastTime)) return fmt.Sprintf("%s%03d%02d%06d", t.Format("20060102150405"), t.Nanosecond()/1e6, g.machineID, seq, ) } // 并发测试函数 func TestConcurrentGeneration() { fmt.Println("=== 并发测试 ===") generator := NewOrderNoGenerator(1) // 使用map检查重复 results := sync.Map{} var wg sync.WaitGroup start := time.Now() // 启动1000个协程同时生成订单号 for i := 0; i < 1000; i++ { wg.Add(1) go func(id int) { defer wg.Done() orderNo := generator.Generate() // 检查是否重复 if _, loaded := results.LoadOrStore(orderNo, true); loaded { fmt.Printf("⚠️ 发现重复订单号: %s\n", orderNo) } }(i) } wg.Wait() elapsed := time.Since(start) // 统计结果 count := 0 results.Range(func(key, value interface{}) bool { count++ return true }) fmt.Printf("生成 %d 个订单号,耗时 %v\n", count, elapsed) fmt.Printf("平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds()) } // 测试V3版本的并发 func TestConcurrentGenerationV3() { fmt.Println("\n=== 测试V3版本并发 ===") generator := NewOrderNoGeneratorV3(1) results := sync.Map{} var wg sync.WaitGroup start := time.Now() // 启动10000个协程同时生成订单号 for i := 0; i < 10000; i++ { wg.Add(1) go func(id int) { defer wg.Done() orderNo := generator.Generate() // 检查是否重复 if _, loaded := results.LoadOrStore(orderNo, true); loaded { fmt.Printf("⚠️ V3 - 发现重复订单号: %s\n", orderNo) } }(i) } wg.Wait() elapsed := time.Since(start) // 统计结果 count := 0 results.Range(func(key, value interface{}) bool { count++ return true }) fmt.Printf("V3 - 生成 %d 个订单号,耗时 %v\n", count, elapsed) fmt.Printf("V3 - 平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds()) } // 压力测试:持续生成订单号 func StressTest() { fmt.Println("\n=== 压力测试 ===") generator := NewOrderNoGeneratorV3(1) results := sync.Map{} duplicateCount := 0 var duplicateMutex sync.Mutex // 持续生成5秒 stop := time.After(5 * time.Second) start := time.Now() for i := 0; ; i++ { select { case <-stop: elapsed := time.Since(start) totalCount := 0 results.Range(func(key, value interface{}) bool { totalCount++ return true }) fmt.Printf("压力测试 - 总生成: %d 个订单号\n", i) fmt.Printf("压力测试 - 唯一订单号: %d 个\n", totalCount) fmt.Printf("压力测试 - 重复数: %d 个\n", duplicateCount) fmt.Printf("压力测试 - 耗时: %v\n", elapsed) fmt.Printf("压力测试 - QPS: %.0f\n", float64(i)/elapsed.Seconds()) return default: orderNo := generator.Generate() if _, loaded := results.LoadOrStore(orderNo, true); loaded { duplicateMutex.Lock() duplicateCount++ duplicateMutex.Unlock() } } } }