平台提供接口

生成guid(值替换为雪花算法)
{ip}/bo/api/v3/db/help/guid
{ip}/bo/api/v3/db/help/snowflake/guid?id=

雪花ID,逆向解析
{ip}/bo/api/v3/db/help/snowflake/analyze/{id}

注入服务

private readonly IGuid _guidRepository;
IGuid guidRepository,
_guidRepository = guidRepository;
public string GetDataGuid

雪花算法 (DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))

开源项目

https://github.com/stulzq/snowflake-net/tree/master/Demo

https://gitee.com/itsm/learning_example/tree/master/snowflake-%E9%9B%AA%E8%8A%B1Id

把guid生成规则改成雪花算法

  /// <summary>
        /// 获取 主键ID信息
        /// </summary>
        /// <param name="ownerId"></param>
        /// <param name="sysId"></param>
        /// <param name="dictionaryUrl"></param>
        /// <param name="noGidSnowflake">是否禁用雪花算法获取ID</param>
        /// <returns></returns>
        public string GetDataGuid([RequiredStringPF("ownerId")] string ownerId, string sysId, Dictionary<string, object> dictionaryUrl, bool noGidSnowflake = false)
        {
            sysId = sysId ?? "sys";
            string envId = EnvPFUtil.CurrentEnv();

            string configKey = $"snowflake:machine:{envId}{ownerId}{sysId}";

            long datacenterId = _configuration.GetValue<long>(configKey);

            if (_configuration.GetValue<bool>("snowflake:machine:no"))
            {
                string guid = Guid.NewGuid().ToString();
                StringBuilder sbGuid = new StringBuilder();
                if (!string.IsNullOrEmpty(ownerId))
                {
                    sbGuid.Append($"{ownerId.Substring(0, ownerId.Length <= 4 ? ownerId.Length : 4)}-".ToLower());
                }
                if (!string.IsNullOrEmpty(envId))
                {
                    sbGuid.Append($"{envId.Substring(0, envId.Length <= 4 ? envId.Length : 4)}-".ToLower());
                }
                if (!string.IsNullOrEmpty(sysId) && sysId.Length > 16)
                {
                    sbGuid.Append($"{sysId.Substring(4, sysId.Length <= 8 ? sysId.Length : 8)}-");
                }
                else if (!string.IsNullOrEmpty(sysId))
                {
                    sbGuid.Append($"{sysId.Substring(0, sysId.Length <= 8 ? sysId.Length : 8)}-");
                }
                // 机器码  用于分布式扩展
                string guidId = GidSnowflakeGuid(datacenterId);// _configuration.GetValue<string>("snowflake:machineId") ?? "";
                                               //处理字符串问题
                sbGuid.Replace("--", "-");
                return $"{guidId}-{sbGuid.ToString()}{guid.Substring(0, 36 - sbGuid.Length - guidId.Length - 1)}".Trim('-').PadRight(36, '0');

            }
            else
            {
                long machineId = _configuration.GetValue<long>("snowflake:machineId");
                GidSnowflakeUtil GidSnowflakeUtil = new GidSnowflakeUtil(machineId, datacenterId);
                return GidSnowflakeUtil.GetId().ToString();
            }
        }

business.json

{
  "snowflake": {
    "machine": {
      "no":false,
      //根据环境变量、项目、系统设置机器码
      "{envId}{ownerId}{sysId}": 0
    }
  }
}

号段解析

1bit: 不用,因为二进制中最高位是符号位,1表示负数,0表示正数,生成的id一般都是用整数,所以最高位固定为0.
41bit-时间戳: 用来记录时间戳,毫秒级.41位可以表示2(41)-1个数字;如果只用来表示正整数(计算机中正数包含0),可以表示的数值范围是:0至2(41)-1,减1是因为可表示的数值范围是从0开始算的,而不是1’也就是说41位可以表示2(41)-1个毫秒的值,转化成单位年则是2(41)-1/(1000606024365)=69年(够用到2039-09-07)
10bit-工作机器id: 用来记录工作机器的id.可以部署在2(10)=1024个节点,包括5位datacenterId和5位workerId;5位(bit)可以表示的最大正整数是2(5)-1=31,即可以用0,1,2,3,…31这32个数字,来表示不同的datacenterId和workerId
12bit-序列号: 用来记录同一毫秒内产生的不同id.12位(bit)可以表示最大正整数是2^{12}-1=4095,即可以用0,1,2,3…4094这4095个数字,来表示同一时间戳内产生的4095个ID序号
SnowFlake可以保证: 所有声称的id按时间趋势递增,整个分布式系统内不会产生重复id(因为有datacenterId和workerId来区分)

文档更新时间: 2024-03-02 10:50   作者:admin