trrtly/php-snowflake

基于Twitter宣布的Snowflake算法的PHP ID生成器。

1.1.3 2021-08-09 12:39 UTC

README

基于Twitter宣布的Snowflake算法的PHP ID生成器。

quality score godruoyi php-snowflake License Packagist Version build passed Total Downloads

描述

Snowflake算法PHP实现 中文文档.

file

Snowflake是一种在保证某些简单条件下的高规模生成唯一ID号的网络服务。

  • 第一位是未使用的符号位。
  • 第二部分由41位时间戳(毫秒)组成,其值是当前时间相对于某个时间的偏移量。
  • 第三部分和第四部分的5位代表数据中心和工作者,最大值为2^5 - 1 = 31。
  • 最后一部分由12位组成,这意味着每个工作节点每毫秒生成的序列号长度,每毫秒最多可以生成2^12 - 1 = 4095个ID。
  • 在分布式环境中,5位数据中心和工作者意味着可以部署31个数据中心,每个数据中心可以部署多达31个节点。
  • 41位的二进制长度最多为2^41 - 1毫秒 = 69年。因此,Snowflake算法可以持续使用69年,为了最大限度地利用算法,应该为其指定一个起始时间。

必须知道,由Snowflake算法生成的ID不保证唯一。例如,当两个不同的请求同时进入同一数据中心同一节点时,并且节点生成的序列号相同,则生成的ID将重复。

因此,如果您想使用Snowflake算法生成唯一ID,您必须确保:同一节点同一毫秒生成的序列号是唯一的。基于此,我们创建了此包,并将其集成到多个序列号提供者中。

  • RandomSequenceResolver (随机)
  • RedisSequenceResolver (基于redis psetex和incrby)
  • LaravelSequenceResolver (基于redis psetex和incrby)
  • SwooleSequenceResolver (基于swoole_lock)

每个提供者只需要确保同一毫秒生成的序列号不同,就可以获得唯一的ID。

要求

  1. PHP >= 7.0
  2. Composer

安装

$ composer require godruoyi/php-snowflake -vvv

用法

  1. 简单易用。
$snowflake = new \Godruoyi\Snowflake\Snowflake;

$snowflake->id();
// 1537200202186752
  1. 指定数据中心ID和工作ID。
$snowflake = new \Godruoyi\Snowflake\Snowflake($datacenterId, $workerId);

$snowflake->id();
  1. 指定起始时间。
$snowflake = new \Godruoyi\Snowflake\Snowflake;
$snowflake->setStartTimeStamp(strtotime('2019-09-09')*1000);

$snowflake->id();

高级

  1. 用于Laravel。

因为SDK相对简单,我们没有为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 () {
            return (new Snowflake())
                ->setStartTimeStamp(strtotime('2019-10-10')*1000)
                ->setSequenceResolver(new LaravelSequenceResolver($this->app->get('cache')->store()));
        });
    }
}
  1. 自定义

您可以通过实现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();

许可证

MIT