标签:serve htm last float 测试 OLE 获取 const 存储
上篇文章主要介绍《实现原理》,这篇看主要代码的编写。
const BITS_FULL = 64;
const BITS_PRE = 2; // 固定位01
const BITS_TIME = 41; // 可支持69年
const BITS_SERVER = 4; // 可支持16台集群服务
const BITS_WORKER = 10; // 可支持业务数1024个
const BITS_SEQUENCE = 7; // 一毫秒内支持生成128个id
private $sequence_id = 0;
private $last_timestamp = 0;
private $server_id = 0;
const EPOCH_TIME = 1540828800000; //时间基数
/**
* 获取id
*/
function get($worker_id = 0)
{
//初始化id位
$id = pow(2, 62);
/* 1. 时间戳 41位 */
$time = $this->timeGen();
$diff_time = $time - self::EPOCH_TIME;
$shift = self::BITS_FULL - self::BITS_PRE - self::BITS_TIME;
$id |= $diff_time << $shift;
/* 2. 服务器id */
$shift -= self::BITS_SERVER;
$id |= ($this->server_id & (pow(2, self::BITS_SERVER) - 1)) << $shift;
/* 3. 业务id */
$shift -= self::BITS_WORKER;
$id |= ($worker_id & (pow(2, self::BITS_WORKER) - 1)) << $shift;
/* 4. 自增id */
$id |= ($this->sequence_id % (pow(2, self::BITS_SEQUENCE) - 1));
$this->sequence_id++;
return $id;
}
/**
* 获取当前时间
*/
function timeGen() {
$wait_next_ms = 0;
do {
if($wait_next_ms > 0) {
usleep(100); //等待下一毫秒,休眠0.1毫秒
}
$timestamp = microtime(true) * 1000;
$timestamp = (int) $timestamp;
if($this->last_timestamp < $timestamp) {
$this->sequence_id = 0;
}
$wait_next_ms++;
} while ($this->last_timestamp == $timestamp
&& $this->sequence_id >= (pow(2, self::BITS_SEQUENCE) - 1)
|| $this->last_timestamp > $timestamp);
$this->last_timestamp = $timestamp;
return $timestamp;
}
$shortopts = ‘s:p‘; // s服务ID编号, p绑定端口
$options = getopt($shortopts);
// 由swoole_table存储最后一次产生数据的相关值
$table = new swoole_table(2048);
$table->column(‘sequence_id‘, swoole_table::TYPE_INT);
$table->column(‘last_timestamp‘, swoole_table::TYPE_FLOAT);
$table->column(‘server_id‘, swoole_table::TYPE_INT);
$table->create();
// atomic分业务加锁
for ($i = 0; $i <= 1023; $i++) {
$atomics[$i] = new swoole_atomic(0);
}
$serv = new Server("0.0.0.0", $options[‘p‘]);
$serv->table = $table;
$serv->atomics = $atomics;
$IDGen_config = array(
‘server_id‘ => $options[‘s‘],
‘last_timestamp‘ => 0,
‘sequence_id‘ => 0,
);
$serv->table->set(‘key:idgen_config‘, $IDGen_config);
$serv->on(‘start‘, function ($serv) use($options) {
// 启动事件
});
//监听redis get指令
$serv->setHandler(‘GET‘, function ($fd, $data) use ($serv) {
$data = trim($data[0]);
$IDGen = new IDGen();
$id = $IDGen->get();
return Server::format(Server::STRING, $id);
});
$serv->start();
redis-cli -h 172.19.19.21 -p 9500
172.19.19.21:9500> get 1
"4747443928557682816"
172.19.19.21:9500> get 2
"4747443933230137600"
分布式ID生成器PHP+Swoole实现(下) - 代码实现
标签:serve htm last float 测试 OLE 获取 const 存储
原文地址:https://www.cnblogs.com/gouyg/p/IDIdentifier-for-php-swoole2.html