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

测试

 1 func testFun() {
2 var count int = 1000000
3 mapId := make(map[int64]int64, count)
4 fmt.Println("start,count:", count)
5 for i := 0; i < count; i++ {
6 id, ts := test.Snow.GetSnowflakeId()
7 mapId[id] = ts
8 }
9 fmt.Println("done,count:", count, ",mapCount:", len(mapId))
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. TCP/IP 协议(10):TCP 协议一百问

    TCP/IP 协议(10):TCP 协议一百问 杨领well 的 TCP/IP 协议专栏 TCP 协议部分一直没有更新,是因为我不确定到底应该怎么来介绍 TCP 协议才能干货满满.最后我决定以 Q&a ...

  2. C# Socket 通信时,怎样判断 Socket 双方是否断开连接

    参考内容: C#socket通信时,怎样判断socket双方是否断开连接 C#之Socket断线和重连 Socket.Poll 方法 Socket.Blocking 属性 最近需要写个网口通信的上位机 ...

  3. [SHOI2006]仙人掌

    [SHOI2006]仙人掌 简要解析 其实很简单 只要普通树形 \(dp\) 就行了 \(f_x\) 表示 \(x\) 能向下延深的最大距离,\(v\) 是 \(x\) 的儿子 当一个点不属于任何环时 ...

  4. 基于IGServer的Web地图要素空间分析

    1. 引言 MapGIS IGServer 是中地数码的一款跨平台GIS 服务器产品,提供了空间数据管理.分析.可视化及共享服务 MapGIS IGServer的下载(试用)地址:MapGIS IGS ...

  5. Vue学习笔记之计算属性、内容分发、自定义事件

    1. 计算属性 计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化 ...

  6. PostgreSQL的10进制与16进制互转

    1.10进制转16进制Postgres里面有一个内置的10进制转16进制的函数:to_hex(int)/to_hex(bigint) [postgres@localhost ~]$ psql Pass ...

  7. 【javascript】slice()、substring()和substr() 三种字符串截取方法区别

    slice(start, end) :slice(start, end) 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分.  1.start(包含) 和 end(不包含) 参数来指定字符串 ...

  8. 自己动手从零写桌面操作系统GrapeOS系列教程——8.x86介绍

    由于GrapeOS目前只支持x86,所以本讲我们简单的介绍一下x86. 百度百科上是这样介绍的:x86泛指一系列基于Intel 8086且向后兼容的中央处理器指令集架构. 中央处理器就是我们平时说的C ...

  9. struct device_node *

    struct device_node *test_node; test_node->name name出不来 struct device_node *test_device_node; test ...

  10. GmSSL3.0密码算法库

    GmSSL3.0密码算法库 一.开发背景 GmSSL 3.0版本具有更快.更小.更安全的特点,相比于GmSSL 2.0我们主要从以下方向进行改进: 采用CMake替代目前基于Perl的构建系统 支持L ...