Snowflake 是 Twitter 內部的一個 ID 生算法,能夠經過一些簡單的規則保證在大規模分佈式狀況下生成惟一的 ID 號碼。php
其組成爲:git
須要注意的是:github
由上可知,雪花算法生成的 ID 並不能保證惟一,如當兩個不一樣請求同一時刻進入相同的數據中心的相同節點時,而此時該節點生成的 sequence 又是相同時,就會致使生成的 ID 重複。redis
因此要想使用雪花算法生成惟一的 ID,就須要保證同一節點同一毫秒內生成的序列號是惟一的。基於此,咱們在 SDK 中集成了多種序列號提供者:算法
不一樣的提供者只須要保證同一毫秒生成的序列號不一樣,就能獲得惟一的 ID。shell
$ composer require godruoyi/php-snowflake -vvv
複製代碼
$snowflake = new \Godruoyi\Snowflake\Snowflake;
$snowflake->id();
// 1537200202186752
複製代碼
$snowflake = new \Godruoyi\Snowflake\Snowflake($datacenterId, $workerId);
$snowflake->id();
複製代碼
$snowflake = new \Godruoyi\Snowflake\Snowflake;
$snowflake->setStartTimeStamp(strtotime('2019-09-09')*1000);
$snowflake->id();
複製代碼
由於 SDK 相對簡單,咱們並無提供 Laravel 的擴展包,你可經過下面的方式快速集成到 Laravel 中。bash
// 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()));
});
}
}
複製代碼
你能夠經過實現 Godruoyi\Snowflake\SequenceResolver 接口來自定義序列號解決器。swoole
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();
複製代碼
若是您在使用過程當中遇到任何問題,歡迎提交 「PR」。app