@dume2007
2018-11-09T12:21:53.000000Z
字数 2314
阅读 2148
php
swoole
- 统一系统业务数据表自增id。支持分布式,id唯一性。通过集群最多一秒内可生成300万个id
- 环境需求:64位系统、swoole
- 组成结构:固定输出格式bigint(19),内含时间戳信息+业务编号id+服务器id信息
- 传输协议:TCP协议,使用swoole进行数据下发
- 64位ID位数分布
空位 | 毫秒级时间戳 | 服务器编号 | 业务编号 | 自增id |
---|---|---|---|---|
2 | 41 | 6 | 7 | 8 |
根据以上位数组成
- 发号器大约可使用 2^41/1000/3600/24/365=70年
- 可部署63台集群
- 支持127个业务
- 单台服务每毫秒可生成255个id,经过实测php生成速度大约为50左右
解压后进入源码ext目录,cd ext
一键生成php扩展所需的基本文件
./ext_skel --extname=IDGen
ext目录下生成了一个IDGen的文件夹,cd IDGen 进入,主要修改三个文件:config.m4,IDGen.c,php_IDGen.h
* config.m4 移除以下几行的dnl注释
PHP_ARG_WITH(IDGen, for IDGen support,
Make sure that the comment is aligned:
[ --with-IDGen Include IDGen support])
* php_IDGen.h 通过宏命令PHP_METHOD 添加想要注册的类方法,比如在文件底部增加:
PHP_METHOD(IDGen, __construct);
PHP_METHOD(IDGen, __destruct);
PHP_METHOD(IDGen, get);
PHP_METHOD(IDGen, parse);
PHP_METHOD(IDGen, getCurrConfig);
* IDGen.c 最后就是在这个文件里编写相应的C扩展了, 譬如我们在h头文件里面注册了五个方法,那么在c里通过PHP_METHOD实现
PHP_METHOD(IDGen, __construct) {
//php_printf("__construct called.\n");
}
PHP_METHOD(IDGen, __destruct) {
//php_printf("__destruct called.\n");
}
PHP_METHOD(IDGen, get) {
}
PHP_METHOD(IDGen, parse) {
}
PHP_METHOD(IDGen, getCurrConfig) {
}
* 在实现以上几个方法之前需对以下几点进行改动:声明类成员函数
const zend_function_entry IDGen_functions[] = {
PHP_ME(IDGen, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(IDGen, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_ME(IDGen, get, NULL, ZEND_ACC_PUBLIC)
PHP_ME(IDGen, parse, NULL, ZEND_ACC_PUBLIC)
PHP_ME(IDGen, getCurrConfig, NULL, ZEND_ACC_PUBLIC)
PHP_FE_END /* Must be the last line in IDGen_functions[] */
}
* 声明类成员属性
zend_class_entry *idgen_ce;
PHP_MINIT_FUNCTION(IDGen)
{
/* If you have INI entries, uncomment these lines
REGISTER_INI_ENTRIES();
*/
zend_class_entry idgen; INIT_CLASS_ENTRY(idgen, "IDGen", IDGen_functions);
idgen_ce = zend_register_internal_class_ex(&idgen, NULL, NULL TSRMLS_CC);
zend_declare_property_null(idgen_ce, ZEND_STRL("server_id"), ZEND_ACC_PRIVATE TSRMLS_CC);
zend_declare_property_null(idgen_ce, ZEND_STRL("sequence_id"), ZEND_ACC_PRIVATE TSRMLS_CC);
zend_declare_property_null(idgen_ce, ZEND_STRL("last_timestamp"), ZEND_ACC_PRIVATE TSRMLS_CC);
return SUCCESS;
}
phpize
./configure
make
sudo make install
查看php.ini位置
php --ini
添加IDGen.so扩展
extension=IDGen.so
php -m
$IDGen = new IDGen;
$id = $IDGen->get(1);
var_dump($id);
$parse = $IDGen->parse($id);
print_r($parse);
本扩展还有待完善优化的地方,纯属学习。另外可参考源码上纯C实现的test_IDGen.c
https://github.com/dume2007/php_extension_idgen