1. 1 /*
  2. 2 * twitter雪花算法golang实现,生成唯一趋势自增id
  3. 3 * 保留位:63位
  4. 4 * 毫秒时间戳:[62-20]43位,时间范围[1970-01-01 00:00:00.000,2248-09-26 15:10:22.207]
  5. 5 * 机器id:[19-12]8位,十进制范围[0,255]
  6. 6 * 序列号:[11-0]12位,十进制范围[0,4095]
  7. 7 * bobo
  8. 8 */
  9. 9
  10. 10 package test
  11. 11
  12. 12 import (
  13. 13 "runtime"
  14. 14 "sync"
  15. 15 "time"
  16. 16 )
  17. 17
  18. 18 type SnowFlake struct {
  19. 19 machineID int64 //机器 id占8位,十进制范围是[0,255]
  20. 20 sn int64 //序列号占12位,十进制范围是[0,4095]
  21. 21 lastTime int64 //上次的时间戳(毫秒级)
  22. 22 _lock sync.Mutex //锁
  23. 23 }
  24. 24
  25. 25 var Snow = &SnowFlake{
  26. 26 lastTime: time.Now().UnixNano() / 1000000,
  27. 27 }
  28. 28
  29. 29 func (c *SnowFlake) lock() {
  30. 30 c._lock.Lock()
  31. 31 }
  32. 32
  33. 33 func (c *SnowFlake) unLock() {
  34. 34 c._lock.Unlock()
  35. 35 }
  36. 36
  37. 37 //获取当前毫秒
  38. 38 func (c *SnowFlake) getCurMilliSecond() int64 {
  39. 39 return time.Now().UnixNano() / 1000000
  40. 40 }
  41. 41
  42. 42 //设置机器id,默认为0,范围[0,255]
  43. 43 func (c *SnowFlake) SetMachineId(mId int64) {
  44. 44 //保留8位
  45. 45 mId = mId & 0xFF
  46. 46 //左移12位,序列号是12位的
  47. 47 mId <<= 12
  48. 48 c.machineID = mId
  49. 49 }
  50. 50
  51. 51 //获取机器id
  52. 52 func (c *SnowFlake) GetMachineId() int64 {
  53. 53 mId := c.machineID
  54. 54 mId >>= 12
  55. 55 return mId | 0xFF
  56. 56 }
  57. 57
  58. 58 //解析雪花(id)
  59. 59 // 返回值
  60. 60 // milliSecond:毫秒数
  61. 61 // mId:机器id
  62. 62 // sn:序列号
  63. 63 func (c *SnowFlake) ParseId(id int64) (milliSecond, mId, sn int64) {
  64. 64 sn = id & 0xFFF
  65. 65 id >>= 12
  66. 66 mId = id & 0xFF
  67. 67 id >>= 8
  68. 68 milliSecond = id & 0x7FFFFFFFFFF
  69. 69
  70. 70 return
  71. 71 }
  72. 72
  73. 73 //毫秒转换成time
  74. 74 func (c *SnowFlake) MilliSecondToTime(milliSecond int64) (t time.Time) {
  75. 75 return time.Unix(milliSecond/1000, milliSecond%1000*1000000)
  76. 76 }
  77. 77
  78. 78 //毫秒转换成"20060102T150405.999Z"
  79. 79 func (c *SnowFlake) MillisecondToTimeTz(ts int64) string {
  80. 80 tm := Snow.MilliSecondToTime(ts)
  81. 81 return tm.UTC().Format("20060102T150405.999Z")
  82. 82 }
  83. 83
  84. 84 //毫秒转换成"2006-01-02 15:04:05.999"
  85. 85 func (c *SnowFlake) MillisecondToTimeDb(ts int64) string {
  86. 86 tm := Snow.MilliSecondToTime(ts)
  87. 87 return tm.UTC().Format("2006-01-02 15:04:05.999")
  88. 88 }
  89. 89
  90. 90 //获取雪花
  91. 91 //返回值
  92. 92 //id:自增id
  93. 93 //ts:生成该id的毫秒时间戳
  94. 94 func (c *SnowFlake) GetSnowflakeId() (id, ts int64) {
  95. 95 curTime := c.getCurMilliSecond()
  96. 96 var sn int64 = 0
  97. 97
  98. 98 c.lock()
  99. 99 // 同一毫秒
  100. 100 if curTime == c.lastTime {
  101. 101 c.sn++
  102. 102 // 序列号占 12 位,十进制范围是 [0,4095]
  103. 103 if c.sn > 4095 {
  104. 104 for {
  105. 105 // 让出当前线程
  106. 106 runtime.Gosched()
  107. 107 curTime = c.getCurMilliSecond()
  108. 108 if curTime != c.lastTime {
  109. 109 break
  110. 110 }
  111. 111 }
  112. 112 c.sn = 0
  113. 113 }
  114. 114 } else {
  115. 115 c.sn = 0
  116. 116 }
  117. 117 sn = c.sn
  118. 118 c.lastTime = curTime
  119. 119 c.unLock()
  120. 120
  121. 121 //当前时间小于上次的时间,系统时间改过了吗?
  122. 122 /*
  123. 123 if curTimeStamp < c.lastTimeStamp {
  124. 124 return 0, curTimeStamp
  125. 125 }
  126. 126 */
  127. 127 //机器id占用8位空间,序列号占用12位空间,所以左移20位
  128. 128 rightBinValue := curTime & 0x7FFFFFFFFFF
  129. 129 rightBinValue <<= 20
  130. 130 id = rightBinValue | c.machineID | sn
  131. 131
  132. 132 return id, curTime
  133. 133 }

测试

  1. 1 func testFun() {
  2. 2 var count int = 1000000
  3. 3 mapId := make(map[int64]int64, count)
  4. 4 fmt.Println("start,count:", count)
  5. 5 for i := 0; i < count; i++ {
  6. 6 id, ts := test.Snow.GetSnowflakeId()
  7. 7 mapId[id] = ts
  8. 8 }
  9. 9 fmt.Println("done,count:", count, ",mapCount:", len(mapId))
  10. 10 }

golang 实现twitter雪花算法的更多相关文章

  1. 一个类似 Twitter 雪花算法 的 连续序号 ID 产生器 SeqIDGenerator

    项目地址 :     https://github.com/kelin-xycs/SeqIDGenerator 今天 QQ 群 里有网友问起产生唯一 ID 的方法 有哪些,  讨论了各种方法 . 有网 ...

  2. mybatis plus 主键生成 Twitter雪花算法 id 及修改id为字符型

    mybatis plus配置主键生成策略为2,就是 使用Twitter雪花算法 生成id spring boot中配置为: GlobalConfiguration conf = new GlobalC ...

  3. Twitter雪花算法 SnowFlake算法 的java实现

    概述 SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序. 原理 Sn ...

  4. Twitter雪花算法SnowFlake算法的java实现

    https://juejin.im/post/5c75132f51882562276c5065 package javaDemo; /** * twitter的snowflake算法 -- java实 ...

  5. Snowflake(雪花算法),什么情况下会冲突?

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 分布式系统中,有一些需要使用全局唯一 ID 的场景,这种时候为了防止 ID 冲突可以使用 36 位的 UUI ...

  6. 分布式Snowflake雪花算法

    前言 项目中主键ID生成方式比较多,但是哪种方式更能提高的我们的工作效率.项目质量.代码实用性以及健壮性呢,下面作了一下比较,目前雪花算法的优点还是很明显的. 优缺点比较 UUID(缺点:太长.没法排 ...

  7. 雪花算法-snowflake

    雪花算法-snowflake 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有 ...

  8. 全局唯一Id:雪花算法

    雪花算法-snowflake 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有 ...

  9. 雪花算法【分布式ID问题】【刘新宇】

    分布式ID 1 方案选择 UUID UUID是通用唯一识别码(Universally Unique Identifier)的缩写,开放软件基金会(OSF)规范定义了包括网卡MAC地址.时间戳.名字空间 ...

  10. 分布式主键解决方案之--Snowflake雪花算法

    0--前言 对于分布式系统环境,主键ID的设计很关键,什么自增intID那些是绝对不用的,比较早的时候,大部分系统都用UUID/GUID来作为主键,优点是方便又能解决问题,缺点是插入时因为UUID/G ...

随机推荐

  1. [清华集训2016] Alice 和 Bob 又在玩游戏

    \(\text{Solution}\) 第一道有向图 \(SG\) 函数的博弈论 有根树,设 \(f[x]\) 表示以 \(x\) 为根子树的 \(SG\) 值 对于分裂的图的 \(SG\) 值为每个 ...

  2. JZOJ 5415. 【NOIP2017提高A组集训10.22】公交运输

    题目 城市中有一条长度为 \(n\) 的道路,每隔 \(1\) 的长度有一个公交车站,编号从 \(0\) 到 \(n\),学校在 \(0\) 号车站的位置.其中每个公交车站(除了 \(n\) 号车站) ...

  3. 深入理解跳表及其在Redis中的应用

    前言 跳表可以达到和红黑树一样的时间复杂度 O(logN),且实现简单,Redis 中的有序集合对象的底层数据结构就使用了跳表.其作者威廉·普评价:跳跃链表是在很多应用中有可能替代平衡树的一种数据结构 ...

  4. JavaSE 对象与类(一)

    对象与类 1.面向对象程序概述 Java是完全面向对象的,必须熟悉OOP才能够编写Java程序. 概念:类class.实例(对象)instance 由类构造(construct)对象的过程称为创建类的 ...

  5. 用C++ 弹奏武侠音乐:沧海一声笑

    前言: 参照网路代码,用编程语言来弹奏一首音乐,搞点轻松的 原文:点击此处 完整代码: 以下为Visual Stuido 2022测试可用,控制台程序.运行之后,会自动弹奏沧海一声笑,并且出现歌词.主 ...

  6. Postgresql架构体系解析

    一.PostgreSQL物理架构 postgresql的物理架构非常简单,它由共享内存.一系列后台进程和数据文件组成. 二.Shared Memory 共享内存是服务器服务器为数据库缓存和事务日志缓存 ...

  7. JavaScript之void

    void是什么 void是JavaScript重要的关键字,该操作符指定要计算一个表达式但不返回. 语法格式: void func() javascript:void func() 或 void (f ...

  8. sd 买送服务,自动带出销售订单行项目

    需要先配置自动带出一行行项目,然后增强代码里去修改带出来的数量,注意事务码的判断,不然影响程序效率 FV45PF0N_NATRAB_SELECTION IF SY-TCODE = 'VA03'. EL ...

  9. [整合] 解决 Dell T640 安装显卡后风扇转速不降低

    最近实验室的dell T640服务器安装了新的GPU.但是安装后发现,风扇太吵了,于是开始着手解决风扇转速过高的问题. 试过ipmi,但是不好用. 最后发现使用racadm可以让服务器重新安静下来. ...

  10. VUE学习-条件渲染

    条件渲染 v-if & v-else-if & v-else <div id="app"> <h1 v-if="type == 'VUE ...