先说下 snowflake 的具体组成:
毫秒时间戳差值+机器编码+流水号
因为 php 不是常驻内存的,所以流水号是有问题的,这也是大多数 github 上的snowflake 的 php 实现的通病,我测试了几个,在大并发情况下,还是生成了同样的 id。所以我自己从新写了下。
github 地址:
PHP 版本:https://github.com/anerg2046/helper
Golang 版本:https://github.com/anerg2046/snowflake
PHP 版本的使用:
首先要安装:
composer require anerg2046/helper
然后就可以使用了
use anerg\helper\Snowflake; $machineId = 1; //机器标识,如果为0或为空会忽略机器标识这一段 // $options 是可选参数 $options = [ 'epoch' => 1532620800000, //一个小于当前时间的毫秒,用于缩减时间位数 'maxMachineBit' => 8, //最大机器标识位数,8->255 10->1023 'maxRandomBit' => 12, //最大随机数位数,12->4095 ]; // 获取一个10进制的唯一ID echo Snowflake::nextId($machineId, $options); // 获取一个36进制的唯一ID echo Snowflake::nextHash($machineId, $options)
Golang 版本的使用
同样需要先安装
go get github.com/anerg2046/snowflake
使用方法
跟 PHP 版本类似有3个参数可以进行设置
- Epoch 设置一个小于当前时间的毫秒数,用于缩短时间位数
- MaxMachineBit 最大的机器标识bit位数,默认是8,取值范围1-255,如果为0会忽略机器标识这一段
- MaxSequenceBit 每毫秒内的流水号bit位数,默认是12,取值范围是0-4095
package main import ( "fmt" "github.com/anerg2046/snowflake" ) func main() { //以下3个参数为可选 snowflake.Epoch = 1532620800000 snowflake.MaxMachineBit = 10 snowflake.MaxSequenceBit = 10 //创建一个机器ID的节点,这里是1,如果为0则会忽略机器标识这一段 node, err := snowflake.NewNode(1) if err != nil { fmt.Println(err) return } //获取一个全局唯一的ID id := node.NextID() //输出为int64类型 fmt.Println(id.Int64()) //输出为string类型 fmt.Println(id.String()) //输出为Base36类型,主要是缩短位数 fmt.Println(id.Base36()) }