先说下 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())
}
