Golang / PHP · 2018年9月7日 0

分布式全局唯一ID,snowflake的PHP,golang实现

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

}