您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

c#分布式ID生成器

2025/3/25 4:09:51发布33次查看
简介
这个是根据twitter的snowflake来写的.这里有中文的介绍.
如上图所示,一个64位id,除了最左边的符号位不用(固定为0,以保证生成的id都是正数),还剩余63位可用.
下面的代码与图中的位数分配略有不同,除了中间部分10bit工作机器id不变,时间戳和序列号的位数是可以根据自己的需求变化的,就是说,你可以把中间的工作机器id往左挪一挪,或往右挪一挪.
代码
/// /// 64位id生成器,最高位为符号位,始终为0,可用位数63. /// 实例编号占10位,范围为0-1023 /// 时间戳和索引共占53位 /// public sealed class idcreator { long timestamp = 0;//当前时间戳 long index = 0;//索引/计数器 long instanceid;//实例编号 int indexbitlength;//索引可用位数 long tsmax = 0;//时间戳最大值 long indexmax = 0; static idcreator _default = new idcreator(); /// /// /// /// 实例编号(0-1023) /// 索引可用位数(1-32).每秒可生成id数等于2的indexbitlength次方.大并发情况下,当前秒内id数达到最大值时,将使用下一秒的时间戳,不影响获取id. /// 初始化时间戳,精确到秒.当之前同一实例生成id的timestamp值大于当前时间的时间戳时, /// 有可能会产生重复id(如持续一段时间的大并发请求).设置inittimestamp比最后的时间戳大一些,可避免这种问题 public idcreator(int instanceid, int indexbitlength, long? inittimestamp = null) { if (instanceid < 0) { //这里给每个实例随机生成个实例编号 random r = new random(); this.instanceid = r.next(0, 1024); } else { this.instanceid = instanceid % 1024; } if (indexbitlength 32) { this.indexbitlength = 32; } else { this.indexbitlength = indexbitlength; } tsmax = convert.toint64(new string('1', 53 - indexbitlength), 2); indexmax = convert.toint64(new string('1', indexbitlength), 2); if (inittimestamp != null) { this.timestamp = inittimestamp.value; } } /// /// 默认每实例每秒生成65536个id,从1970年1月1日起,累计可使用4358年 /// /// 实例编号(0-1023) public idcreator(int instanceid) : this(instanceid, 16) { } /// /// 默认每秒生成65536个id,从1970年1月1日起,累计可使用4358年 /// public idcreator() : this(-1) { } /// /// 生成64位id /// /// public long create() { long id = 0; lock (this) { //增加时间戳部分 long ts = harry.common.utils.gettimestamp() / 1000; ts = ts % tsmax; //如果超过时间戳允许的最大值,从0开始 id = ts << (10 + indexbitlength);//腾出后面部分,给实例编号和缩引编号使用 //增加实例部分 id = id | (instanceid << indexbitlength); //获取计数 if (timestamp indexmax) { timestamp++; index = 0; } } id = id | index; index++; } return id; } /// /// 获取当前实例的时间戳 /// public long currenttimestamp { get { return this.timestamp; } } /// /// 默认每实例每秒生成65536个id,从1970年1月1日起,累计可使用4358年 /// public static idcreator default { get { return _default; } } }
代码说明
使用时,需要new一个idcreator的实例,然后调用create()方法,生成一个id号.需要把idcreator的例实赋给一个静态变量,以保证id号的唯一性.如果是分布式部署,需要给idcreator的构造函数传递instanceid参数,每一个部署都要有一个不同的值,范围为0-1023.
构造函数中的indexbitlength参数,代表图中最右边的'序列号'的长度,不再固定为12bit,范围为1-32.剩下的可用位,就留给了时间戳.
注意:idcreator类的时间戳是按秒计的. 如果想改成毫秒,只需要将代码long ts = harry.common.utils.gettimestamp() / 1000;改成long ts = harry.common.utils.gettimestamp();即可.
示例代码
idcreator c=new idcreator(0,16); var id=c.create();
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product