生成timeuuid_golang 生成数字UUID 改进版(保持原有数据时间戳顺序)

针对Golang中使用UnixNano()在高并发下可能出现键ID重复的问题,文章提出了一种改进方法,结合UnixNano时间和CRC32哈希的UUID生成策略,确保在并发环境中生成的ID唯一且保持时间顺序。通过并发测试验证了该方法的有效性。
摘要由CSDN通过智能技术生成

问题:Golang 使用UnixNano()作为唯一键id,在高并发环境下出现重复,

package main

import (

"fmt"

"github.com/fwhezfwhez/go-queue"

"runtime"

"strconv"

"sync"

"time"

)

var mutex sync.Mutex

func main() {

runtime.GOMAXPROCS(runtime.NumCPU())

wg := sync.WaitGroup{}

var loopCount int = 5000

var queue = Queue.NewEmpty()

for i := 0; i < loopCount; i++ {

wg.Add(1)

go func(in int, q *Queue.Queue) {

tmp := getNum()

q.SafePush(tmp)

fmt.Println("finish " + strconv.Itoa(in) + ",produce:" + strconv.FormatInt(tmp, 10))

wg.Done()

}(i, queue)

}

wg.Wait()

//queue.Print() // 输入所有UUID

if (queue.ValidLength() == loopCount) {

fmt.Println("生成", loopCount, "个UUID数量,没发现重复,继续测试。")

fmt.Println("备注:若运行没有输出,证明是有重复,程序结束。")

}

}

func getNum() int64 {

mutex.Lock()

defer mutex.Unlock()

return time.Now().UnixNano()

}

运行结果,发现重复:

14b212db7ae7e2d6440d4309d1f06592.png

改进版本-1:数字UUID改进版 (unixNano + hashCode(uuid))

package main

import (

"fmt"

"github.com/fwhezfwhez/go-queue"

uuid "github.com/satori/go.uuid"

"hash/crc32"

"runtime"

"strconv"

"sync"

"time"

)

var mutex sync.Mutex

func main() {

runtime.GOMAXPROCS(runtime.NumCPU())

wg := sync.WaitGroup{}

var loopCount int = 5000

var queue = Queue.NewEmpty()

for i := 0; i < loopCount; i++ {

wg.Add(1)

go func(in int, q *Queue.Queue) {

tmp := getNum()

q.SafePush(tmp)

fmt.Println("finish " + strconv.Itoa(in) + ",produce:" + tmp)

wg.Done()

}(i, queue)

}

wg.Wait()

//queue.Print() // 输入所有UUID

if (queue.ValidLength() == loopCount) {

fmt.Println("生成", loopCount, "个UUID数量,没发现重复,继续测试。")

fmt.Println("备注:若运行没有输出,证明是有重复,程序结束。")

}

}

//改进方法

func getNum() string {

mutex.Lock()

defer mutex.Unlock()

currentTime := time.Now()

timestamp := currentTime.UnixNano()

uuid,_ := uuid.NewV4()

uuidHash := int(crc32.ChecksumIEEE([]byte(uuid.String())))

if -uuidHash >= 0 {

uuidHash = -uuidHash

}

uuidStr := strconv.FormatInt(timestamp,10)+strconv.Itoa(uuidHash)

return uuidStr

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值