order.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package order
  2. import (
  3. "fmt"
  4. "sync"
  5. "sync/atomic"
  6. "time"
  7. )
  8. // 更安全的版本:带毫秒时间戳
  9. type Generator struct {
  10. machineID int
  11. lastTime int64 // 上次时间(毫秒)
  12. sequence int64
  13. mu sync.Mutex
  14. }
  15. func NewOrderNoGenerator(machineID int) *Generator {
  16. return &Generator{
  17. machineID: machineID,
  18. lastTime: time.Now().UnixMilli(),
  19. sequence: 0,
  20. }
  21. }
  22. func (g *Generator) Generate() string {
  23. g.mu.Lock()
  24. defer g.mu.Unlock()
  25. currentTime := time.Now().UnixMilli()
  26. if currentTime == g.lastTime {
  27. g.sequence++
  28. } else {
  29. g.sequence = 1
  30. g.lastTime = currentTime
  31. }
  32. // 格式化时间,包含毫秒
  33. t := time.UnixMilli(currentTime)
  34. // 格式:年月日时分秒 + 毫秒(3位) + 机器ID + 序列号
  35. return fmt.Sprintf("%s%03d%02d%04d",
  36. t.Format("20060102150405"), // 14位
  37. t.Nanosecond()/1e6, // 3位毫秒
  38. g.machineID, // 2位
  39. g.sequence, // 4位
  40. )
  41. }
  42. // GenerateString 生成字符串格式订单号
  43. func (g *Generator) GenerateString(prefix string) string {
  44. // 调用无锁Generate获取ID
  45. id := g.Generate()
  46. // 格式化为字符串
  47. return fmt.Sprintf("%s%s", prefix, id)
  48. }
  49. type GeneratorV3 struct {
  50. machineID int
  51. // 使用一个64位整数存储时间戳(42位)和序列号(22位)
  52. // 这样可以原子操作,不需要锁
  53. counter uint64
  54. }
  55. func NewOrderNoGeneratorV3(machineID int) *GeneratorV3 {
  56. return &GeneratorV3{
  57. machineID: machineID,
  58. counter: 0,
  59. }
  60. }
  61. func (g *GeneratorV3) Generate() string {
  62. // 获取当前毫秒时间戳
  63. now := uint64(time.Now().UnixMilli())
  64. // 原子操作获取下一个ID
  65. var lastTime, seq uint64
  66. for {
  67. old := atomic.LoadUint64(&g.counter)
  68. lastTime = old >> 22 // 高42位是时间戳
  69. seq = old & 0x3FFFFF // 低22位是序列号
  70. if now > lastTime {
  71. // 时间戳变化,重置序列号
  72. seq = 0
  73. lastTime = now
  74. } else if seq >= 0x3FFFFF { // 序列号达到最大值
  75. // 等待下一毫秒
  76. for now <= lastTime {
  77. time.Sleep(100 * time.Microsecond)
  78. now = uint64(time.Now().UnixMilli())
  79. }
  80. seq = 0
  81. lastTime = now
  82. } else {
  83. seq++
  84. }
  85. newVal := (lastTime << 22) | (seq & 0x3FFFFF)
  86. if atomic.CompareAndSwapUint64(&g.counter, old, newVal) {
  87. break
  88. }
  89. }
  90. // 格式化输出
  91. t := time.UnixMilli(int64(lastTime))
  92. return fmt.Sprintf("%s%03d%02d%06d",
  93. t.Format("20060102150405"),
  94. t.Nanosecond()/1e6,
  95. g.machineID,
  96. seq,
  97. )
  98. }
  99. // 并发测试函数
  100. func TestConcurrentGeneration() {
  101. fmt.Println("=== 并发测试 ===")
  102. generator := NewOrderNoGenerator(1)
  103. // 使用map检查重复
  104. results := sync.Map{}
  105. var wg sync.WaitGroup
  106. start := time.Now()
  107. // 启动1000个协程同时生成订单号
  108. for i := 0; i < 1000; i++ {
  109. wg.Add(1)
  110. go func(id int) {
  111. defer wg.Done()
  112. orderNo := generator.Generate()
  113. // 检查是否重复
  114. if _, loaded := results.LoadOrStore(orderNo, true); loaded {
  115. fmt.Printf("⚠️ 发现重复订单号: %s\n", orderNo)
  116. }
  117. }(i)
  118. }
  119. wg.Wait()
  120. elapsed := time.Since(start)
  121. // 统计结果
  122. count := 0
  123. results.Range(func(key, value interface{}) bool {
  124. count++
  125. return true
  126. })
  127. fmt.Printf("生成 %d 个订单号,耗时 %v\n", count, elapsed)
  128. fmt.Printf("平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds())
  129. }
  130. // 测试V3版本的并发
  131. func TestConcurrentGenerationV3() {
  132. fmt.Println("\n=== 测试V3版本并发 ===")
  133. generator := NewOrderNoGeneratorV3(1)
  134. results := sync.Map{}
  135. var wg sync.WaitGroup
  136. start := time.Now()
  137. // 启动10000个协程同时生成订单号
  138. for i := 0; i < 10000; i++ {
  139. wg.Add(1)
  140. go func(id int) {
  141. defer wg.Done()
  142. orderNo := generator.Generate()
  143. // 检查是否重复
  144. if _, loaded := results.LoadOrStore(orderNo, true); loaded {
  145. fmt.Printf("⚠️ V3 - 发现重复订单号: %s\n", orderNo)
  146. }
  147. }(i)
  148. }
  149. wg.Wait()
  150. elapsed := time.Since(start)
  151. // 统计结果
  152. count := 0
  153. results.Range(func(key, value interface{}) bool {
  154. count++
  155. return true
  156. })
  157. fmt.Printf("V3 - 生成 %d 个订单号,耗时 %v\n", count, elapsed)
  158. fmt.Printf("V3 - 平均每秒生成: %.0f 个\n", float64(count)/elapsed.Seconds())
  159. }
  160. // 压力测试:持续生成订单号
  161. func StressTest() {
  162. fmt.Println("\n=== 压力测试 ===")
  163. generator := NewOrderNoGeneratorV3(1)
  164. results := sync.Map{}
  165. duplicateCount := 0
  166. var duplicateMutex sync.Mutex
  167. // 持续生成5秒
  168. stop := time.After(5 * time.Second)
  169. start := time.Now()
  170. for i := 0; ; i++ {
  171. select {
  172. case <-stop:
  173. elapsed := time.Since(start)
  174. totalCount := 0
  175. results.Range(func(key, value interface{}) bool {
  176. totalCount++
  177. return true
  178. })
  179. fmt.Printf("压力测试 - 总生成: %d 个订单号\n", i)
  180. fmt.Printf("压力测试 - 唯一订单号: %d 个\n", totalCount)
  181. fmt.Printf("压力测试 - 重复数: %d 个\n", duplicateCount)
  182. fmt.Printf("压力测试 - 耗时: %v\n", elapsed)
  183. fmt.Printf("压力测试 - QPS: %.0f\n", float64(i)/elapsed.Seconds())
  184. return
  185. default:
  186. orderNo := generator.Generate()
  187. if _, loaded := results.LoadOrStore(orderNo, true); loaded {
  188. duplicateMutex.Lock()
  189. duplicateCount++
  190. duplicateMutex.Unlock()
  191. }
  192. }
  193. }
  194. }