| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- 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()
- }
- }
- }
- }
|