雪花算法 php
雪花算法是一种分布式唯一ID生成算法,可以保证在分布式环境下,生成的ID是唯一的。以下是一个PHP实现的雪花算法:
class Snowflake {
const EPOCH = 1479533469598; //起始时间戳,可以设置自己的起始时间
const SEQUENCE_BITS = 12; //序列号占用的位数
const WORKER_ID_BITS = 5; //机器标识占用的位数
const DATACENTER_ID_BITS = 5; //数据中心占用的位数
private $workerId; //机器标识
private $datacenterId; //数据中心标识
private $sequence = 0; //序列号
private $lastTimestamp = -1; //上次生成的时间戳
public function __construct($workerId, $datacenterId) {
$maxWorkerId = -1 ^ (-1 << self::WORKER_ID_BITS);
$maxDatacenterId = -1 ^ (-1 << self::DATACENTER_ID_BITS);
if ($workerId > $maxWorkerId || $workerId < 0) {
throw new Exception("workerId can't be greater than {$maxWorkerId} or less than 0");
}
if ($datacenterId > $maxDatacenterId || $datacenterId < 0) {
throw new Exception("datacenterId can't be greater than {$maxDatacenterId} or less than 0");
}
$this->workerId = $workerId;
$this->datacenterId = $datacenterId;
}
public function nextId() {
$timestamp = $this->timeGen();
if ($timestamp < $this->lastTimestamp) {
throw new Exception("Clock moved backwards. Refusing to generate id for " . ($this->lastTimestamp - $timestamp) . " milliseconds");
}
if ($timestamp == $this->lastTimestamp) {
$this->sequence = ($this->sequence + 1) & (-1 ^ (-1 << self::SEQUENCE_BITS));
if ($this->sequence == 0) {
$timestamp = $this->tilNextMillis($this->lastTimestamp);
}
} else {
$this->sequence = 0;
}
$this->lastTimestamp = $timestamp;
$timestamp = ($timestamp - self::EPOCH) << (self::SEQUENCE_BITS + self::WORKER_ID_BITS + self::DATACENTER_ID_BITS);
$workerId = $this->workerId << (self::SEQUENCE_BITS + self::DATACENTER_ID_BITS);
$datacenterId = $this->datacenterId << self::SEQUENCE_BITS;
return $timestamp | $workerId | $datacenterId | $this->sequence;
}
private function tilNextMillis($lastTimestamp) {
$timestamp = $this->timeGen();
while ($timestamp <= $lastTimestamp) {
$timestamp = $this->timeGen();
}
return $timestamp;
}
private function timeGen() {
return floor(microtime(true) * 1000);
}
}
使用示例:
$snowflake = new Snowflake(1, 2); //机器标识为1,数据中心标识为2
echo $snowflake->nextId();
注:该PHP实现未考虑并发安全问题,如果需要高并发下使用,请自行添加相关的并发控制机制。
原文地址: https://www.cveoy.top/t/topic/bjm3 著作权归作者所有。请勿转载和采集!