企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 介绍 在分布式系统中,生成全局唯一的ID是一项常见的需求。Snowflake是Twitter开源的一种分布式ID生成算法,它可以在分布式环境下生成唯一的、趋势递增的ID,且不依赖于中央服务器。本文将介绍Snowflake算法的原理,并使用PHP实现一个简单的Snowflake生成器。 ![](https://img.kancloud.cn/77/8e/778e87f42a26d7d926781a5e31b16af8_1694x878.png) ## 雪花算法结构 > Snowflake算法生成的ID由64位组成,其中各部分的位数如下所示: ![](https://img.kancloud.cn/7f/26/7f26c2127cdc8c884d0010ac1689c8f3_603x135.png) ``` 1位符号位 | 41位时间戳 | 10位工作机器ID | 12位序列号 ``` 1. **符号位**:始终为0,保证生成的ID为正整数。因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。 2. **时间戳**:使用41位来表示当前时间戳,精确到毫秒级,可以使用69年。41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2 ^ 41 - 1 个毫秒值,换算成年就是表示 69 年的时间。 3. **工作机器ID**:用于区分不同的工作节点,可以分配的工作机器ID范围为0~1023。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2 ^ 5 个机房(32 个机房),每个机房里可以代表 2 ^ 5 个机器(32 台机器),这里可以随意拆分,比如拿出4位标识业务号,其他6位作为机器号。可以随意组合。 4. **序列号**:用于解决同一毫秒内并发生成多个ID的冲突问题,可以支持每毫秒最多生成4096个ID。12 bit 可以代表的最大正整数是 2 ^ 12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。也就是同一毫秒内同一台机器所生成的最大ID数量为4096 ## 安装 ``` composer require godruoyi/php-snowflake -vvv ``` ## 简单使用 ``` <?php /** * @desc snowflake * @author Tinywan(ShaoBo Wan) * @date 2024/8/14 22:45 */ require '../vendor/autoload.php'; $snowflake = new \Godruoyi\Snowflake\Snowflake; echo $snowflake->id() . PHP_EOL; ``` 执行输出 ``` 663985260597348711 ``` **指定数据中心ID及机器ID** ``` $datacenterId = time(); $workerId = '1000000000000001'; $snowflake = new \Godruoyi\Snowflake\Snowflake($datacenterId, $workerId); echo $snowflake->id() . PHP_EOL; ``` 执行输出 ``` 663986323404837079 ``` **指定开始时间** ``` $snowflake = new \Godruoyi\Snowflake\Snowflake; $snowflake->setStartTimeStamp(strtotime('2020-08-15')*1000); echo $snowflake->id() . PHP_EOL; ``` 执行输出 ``` 528938994126294755 ``` ## 高级用法 #### 在 Laravel 中使用 可通过下面的方式快速集成到 Laravel 中 ``` // App\Providers\AppServiceProvider use Godruoyi\Snowflake\Snowflake; use Godruoyi\Snowflake\LaravelSequenceResolver; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { $this->app->singleton('snowflake', function ($app) { return (new Snowflake()) ->setStartTimeStamp(strtotime('2019-10-10')*1000) ->setSequenceResolver(new LaravelSequenceResolver($app->get('cache.store'))); }); } } } ``` #### 自定义序列号解决器 你可以通过实现 `Godruoyi\\Snowflake\\SequenceResolver` 接口来自定义序列号解决器。 ``` class YourSequence implements SequenceResolver { /** * {@inheritdoc} */ public function sequence(int $currentTime) { // Just test. return mt_rand(0, 1); } } // usage $snowflake->setSequenceResolver(new YourSequence); $snowflake->id(); ``` 你也可以直接使用闭包: ``` $snowflake = new \Godruoyi\Snowflake\Snowflake; $snowflake->setSequenceResolver(function ($currentTime) { static $lastTime; static $sequence; if ($lastTime == $currentTime) { ++$sequence; } else { $sequence = 0; } $lastTime = $currentTime; return $sequence; })->id(); ``` ## 小结 本文介绍了Snowflake算法的原理,并使用PHP实现了一个简单的Snowflake生成器。Snowflake算法可以在分布式系统中生成唯一的、趋势递增的ID,并且不依赖于中央服务器。 在实际应用中,我们可以将Snowflake生成器集成到分布式系统中,用于生成全局唯一的ID,满足分布式环境下的唯一ID需求。希望本文的介绍能够帮助读者了解Snowflake算法的实现原理,并在实际开发中使用Snowflake生成器生成分布式唯一ID。