snowflake算法 php,雪花算法-PHP

该博客介绍了雪花算法(SnowFlake),一种用于生成全局唯一ID的分布式算法。主要包含时间戳、工作机器ID和序列号三部分,确保在多节点环境下生成不重复的ID。文章详细解释了算法的工作原理及其实现细节,包括如何处理时钟回拨问题和生成ID的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

namespace App;

class SnowFlake

{

//开始时间,固定一个小于当前时间的毫秒数即可

const twepoch = 1474992000000;//2016/9/28 0:0:0

//机器标识占的位数

const workerIdBits = 10;

//毫秒内自增数点的位数

const sequenceBits = 12;

protected $workId = 0;

//要用静态变量

static $lastTimestamp = -1;

static $sequence = 0;

function __construct($workId){

//机器ID范围判断

$maxWorkerId = -1 ^ (-1 << self::workerIdBits);

if($workId > $maxWorkerId || $workId< 0){

throw new Exception("workerId can't be greater than ".$maxWorkerId." or less than 0");

}

//赋值

$this->workId = $workId;

}

//生成一个ID

public function nextId(){

$timestamp = $this->timeGen();

$lastTimestamp = self::$lastTimestamp;

//判断时钟是否正常

if ($timestamp < $lastTimestamp) {

throw new Exception("Clock moved backwards. Refusing to generate id for %d milliseconds", ($lastTimestamp - $timestamp));

}

//生成唯一序列

if ($lastTimestamp == $timestamp) {

$sequenceMask = -1 ^ (-1 << self::sequenceBits);

self::$sequence = (self::$sequence + 1) & $sequenceMask;

if (self::$sequence == 0) {

$timestamp = $this->tilNextMillis($lastTimestamp);

}

} else {

self::$sequence = 0;

}

self::$lastTimestamp = $timestamp;

//

//时间毫秒/数据中心ID/机器ID,要左移的位数

$timestampLeftShift = self::sequenceBits + self::workerIdBits;

$workerIdShift = self::sequenceBits;

//组合3段数据返回: 时间戳.工作机器.序列

$nextId = (($timestamp - self::twepoch) << $timestampLeftShift) | ($this->workId << $workerIdShift) | self::$sequence;

return $nextId;

}

//取当前时间毫秒

protected function timeGen(){

$timestramp = (float)sprintf("%.0f", microtime(true) * 1000);

return $timestramp;

}

//取下一毫秒

protected function tilNextMillis($lastTimestamp) {

$timestamp = $this->timeGen();

while ($timestamp <= $lastTimestamp) {

$timestamp = $this->timeGen();

}

return $timestamp;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值