雪花算法的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),效率较高。但是依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能会造成id冲突或者重复。可以根据服务器内网ip来作为机器的id,保证唯一性。
class SnowFlake {
protected static $instance;
private static $machineId;
private function __construct() {
self::$machineId = ip2long(gethostbyname(gethostname()));
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function createID(){
// 假设一个机器id
// $machineId = ip2long(gethostbyname(gethostname()));
//41bit timestamp(毫秒)
$time = floor(microtime(true) * 1000);
//0bit 未使用
$suffix = 0;
//datacenterId 添加数据的时间
$base = decbin(pow(2,40) - 1 + $time);
//workerId 机器ID
$machineid = decbin(pow(2,9) - 1 + self::$machineId);
//毫秒类的计数
$random = mt_rand(1, pow(2,11)-1);
$random = decbin(pow(2,11)-1 + $random);
//拼装所有数据
$base64 = $suffix.$base.$machineid.$random;
//将二进制转换int
$base64 = bindec($base64);
return sprintf('%.0f', $base64);
}
}
$id = (SnowFlake::getInstance())->createID();