您现在的位置是:首页 > 技术笔记 > Go语言Go语言

go语言实现生成唯一UUID

冰山2019-12-25【Go语言】人已围观

简介前不久,在业务开发过程中,有需要用到生成唯一UID作为标识的地方,当时用的方法是时间戳作为标识,但是后来根据数据发现,短时间内生成的时间戳会有重复的,便写了个生成唯一UI的工具

前不久,在业务开发过程中,有需要用到生成唯一UID作为标识的地方,当时用的方法是时间戳作为标识,但是后来根据数据发现,短时间内生成的时间戳会有重复的,便写了个生成唯一UI的工具。

 
virt-install --virt-type kvm --name "xxxServer" \ --vcpus 6 \ --ram 8192 \ --disk path=/opt/kvm/xxxServer/xxxServer.qcow2 \ --network bridge=br1,model=virtio \ --graphics vnc,listen=127.0.0.1 \ --location=/opt/CentOS-7-x86_64-Everything-1810.iso \ --os-type=linux --os-variant=rhel7 \ --extra-args="console=tty0 console=ttyS0,115200n8 edd=off"

// Package snowflake provides a very simple Twitter snowflake generator and parser.
// +-------------------------------------------------------+
// | 42 Bit Timestamp | 10 Bit WorkID | 12 Bit Sequence ID |
// +-------------------------------------------------------+
package snowflake

import (
	"sync"
	"errors"
	"time"
)

const (
	epoch int64 = 1526285084373

	numWorkerBits = 10

	numSequenceBits = 12

	MaxWorkId = -1 ^ (-1 << numWorkerBits)

	MaxSequence = -1 ^ (-1 << numSequenceBits)
)

type SnowFlake struct {
	lastTimestamp uint64
	sequence      uint32
	workerId      uint32
	lock          sync.Mutex
}

func (sf *SnowFlake) pack() uint64 {
	uuid := (sf.lastTimestamp << (numWorkerBits + numSequenceBits)) | (uint64(sf.workerId) << numSequenceBits) | (uint64(sf.sequence))
	return uuid
}

// New returns a new snowflake node that can be used to generate snowflake
func New(workerId uint32) (*SnowFlake, error) {
	if workerId < 0 || workerId > MaxWorkId {
		return nil, errors.New("invalid worker Id")
	}
	return &SnowFlake{workerId: workerId}, nil
}

// Next creates and returns a unique snowflake ID
func (sf *SnowFlake) Generate() (uint64, error) {
	sf.lock.Lock()
	defer sf.lock.Unlock()

	ts := timestamp()
	if ts == sf.lastTimestamp {
		sf.sequence = (sf.sequence + 1) & MaxSequence
		if sf.sequence == 0 {
			ts = sf.waitNextMilli(ts)
		}
	} else {
		sf.sequence = 0
	}

	if ts < sf.lastTimestamp {
		return 0, errors.New("invalid system clock")
	}

	sf.lastTimestamp = ts
	return sf.pack(), nil
}

// waitNextMilli if that microsecond is full
// wait for the next microsecond
func (sf *SnowFlake) waitNextMilli(ts uint64) uint64 {
	for ts == sf.lastTimestamp {
		time.Sleep(100 * time.Microsecond)
		ts = timestamp()
	}
	return ts
}

// timestamp
func timestamp() uint64 {
	return uint64(time.Now().UnixNano()/int64(1000000) - epoch)
}

调用方法:

 
virt-install --virt-type kvm --name "xxxServer" \ --vcpus 6 \ --ram 8192 \ --disk path=/opt/kvm/xxxServer/xxxServer.qcow2 \ --network bridge=br1,model=virtio \ --graphics vnc,listen=127.0.0.1 \ --location=/opt/CentOS-7-x86_64-Everything-1810.iso \ --os-type=linux --os-variant=rhel7 \ --extra-args="console=tty0 console=ttyS0,115200n8 edd=off"

// Create a new Node with a Node number of 1
sf,_:= snowflake.New(1)
uuid,_ := sf.Generate()

  • 微信扫一扫~
  • 支付宝扫一扫~

很赞哦! ()

上一篇:Git常用基本用法

下一篇:返回列表

相关文章

文章评论

本站推荐