Snowflake是Twitter内部的ID生成算法,可以通过一些简单的规则保证在大规模分布式情况下生成唯一的ID号。它的组成是:第一位是未使用的符号位。第二部分由一个41位的时间戳(毫秒)组成,其值是当前时间相对于某个时间的偏移量。第三和第四部分的5位代表数据中心和机器ID,它能代表的最大值是2^5-1=31;最后一部分由12位组成,代表每个工作节点每毫秒生成的序号ID,同一毫秒内最多可以生成2^12-1即4095个ID。需要注意的是,在分布式环境中,datacenter和worker的5位表示最多可以部署31个数据中心,每个数据中心最多可以部署31个节点。41位的二进制长度最多可以表示2^41-1毫秒,也就是69年,所以雪花算法最多可以正常使用69年。为了最大限度地使用该算法,您应该为其指定一个开始时间。由上可知,雪花算法生成的ID不能保证唯一。例如,当两个不同的请求同时进入同一个数据中心的同一个节点,此时节点生成的序列是相同的,则生成的DuplicateID。因此,如果要使用雪花算法生成唯一ID,需要保证同一毫秒内同一节点生成的序列号是唯一的。基于此,我们在SDK中集成了多种序列号提供器:RandomSequenceResolver(随机生成)RedisSequenceResolver(基于redispsetex和incrby生成)LaravelSequenceResolver(基于redispsetex和incrby生成)SwooleSequenceResolver(基于swoole_lock锁)不同providersonly需要保证同一毫秒内产生的序列号不同,才能获得唯一的ID。需要PHP>=7.0Composer安装$composerrequiregodruoyi/php-snowflake-vvv易于使用。$snowflake=new\Godruoyi\Snowflake\Snowflake;$snowflake->id();//1537200202186752指定数据中心ID和机器ID.$??snowflake=new\Godruoyi\Snowflake\Snowflake($datacenterId,$workerId);$snowflake->id();指定开始时间。$snowflake=new\Godruoyi\Snowflake\Snowflake;$snowflake->setStartTimeStamp(strtotime('2019-09-09')*1000);$雪花->id();Advanced在Laravel中使用,因为SDK比较简单,我们不提供Laravel扩展包,您可以通过以下方式快速集成到Laravel中。//App\Providers\AppServiceProvideruseGodruoyi\Snowflake\Snowflake;useGodruoyi\Snowflake\LaravelSequenceResolver;classAppServiceProviderextendsServiceProvider{/***注册任何应用服务。**@returnvoid*/publicfunctionregister(){$this->app->singleton('snowflake',function(){return(newSnowflake())->setStartTimeStamp(strtotime('2019-10-10')*1000)->setSequenceResolver(newLaravelSequenceResolver($this->app->get('cache')->store()));});}}自定义序列号解析器您可以通过实现GodruoyiSnowflakeSequenceResolver接口来自定义序列号解析器。classYourSequenceimplementsSequenceResolver{/***{@inheritdoc}*/publicfunctionsequence(int$currentTime){//只是测试。返回mt_rand(0,1);}}//用法$snowflake->setSequenceResolver(newYourSequence);$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”。
