liuyajian/php-snowflake

基于Snowflake算法(Twitter发布)的PHP ID生成器。

v1.3 2024-01-04 03:21 UTC

This package is not auto-updated.

Last update: 2024-09-26 07:12:42 UTC


README

基于Snowflake算法(Twitter发布)的PHP ID生成器。

</a>
<a href="https://github.com/godruoyi/php-snowflake">
  <image src="https://poser.pugx.org/godruoyi/php-snowflake/license" alt="License">
</a>
<a href="https://packagist.org.cn/packages/godruoyi/php-snowflake">
  <image src="https://poser.pugx.org/godruoyi/php-snowflake/v/stable" alt="Packagist Version">
</a>
<a href="https://github.com/godruoyi/php-snowflake">
  <image src="https://poser.pugx.org/godruoyi/php-snowflake/downloads" alt="Total Downloads">
</a>

描述

Snowflake算法PHP实现 中文文档.

file

Snowflake是一种高规模生成唯一ID号码的网络服务,并保证一些简单的要求。

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

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

因此,如果您想使用雪崩算法生成唯一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