分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

分布式ID生成器PHP+Swoole实现(下) - 代码实现

发布时间:2023-09-06 02:20责任编辑:董明明关键词:PHP

上篇文章主要介绍《实现原理》,这篇看主要代码的编写。

实现IDGenerator类

  • 64位ID由以下元素组成:固定位占2位,时间戳占41位,服务实例数字编号占4位,业务编号占10位,自增id占7位
const BITS_FULL ????= 64;const BITS_PRE ?????= 2; ?// 固定位01const BITS_TIME ????= 41; // 可支持69年const BITS_SERVER ??= 4; ?// 可支持16台集群服务const BITS_WORKER ??= 10; ?// 可支持业务数1024个const BITS_SEQUENCE = 7; ?// 一毫秒内支持生成128个id
  • 定义好三个变量:
    • $sequence_id: 自增序列id,在同一毫秒内产生的ID由此变量进行递增区分
    • $last_timestamp: 最后一次产生ID时的毫秒级时间戳,与下一次生成ID时的时间进行比较,如果时间相同则进行$sequence_id++,如果不同$sequence_id置0从新开始计算。
    • $server_id: 服务器id编号,代表不同的分布式服务实例,服务启动时指定。
private $sequence_id ???= 0;private $last_timestamp = 0;private $server_id = 0;
  • EPOCH_TIME,由过去最近的一个时间值作为比较基数,如下值为2018-10-30 00:00:00
const EPOCH_TIME = 1540828800000; //时间基数
  • 获取一个64位ID主要由以下位运算完成
/** * 获取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;}

实现Swoole redis服务

$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连接测试

redis-cli -h 172.19.19.21 -p 9500172.19.19.21:9500> get 1"4747443928557682816"172.19.19.21:9500> get 2"4747443933230137600"

分布式ID生成器PHP+Swoole实现(下) - 代码实现

原文地址:https://www.cnblogs.com/gouyg/p/IDIdentifier-for-php-swoole2.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved