Pārlūkot izejas kodu

Merge branch 'master' of http://123.60.180.165:4647/ZZYDOP/DOPCore

zhengly 3 gadi atpakaļ
vecāks
revīzija
6a3ecdfcb9

+ 12 - 0
.gitignore

@@ -206,3 +206,15 @@ MicroServices/Business/Bussiness.Model/bin/Debug/net6.0/Business.Domain.pdb
 MicroServices/Business/Bussiness.Model/bin/Debug/net6.0/Business.EntityFrameworkCore.dll
 MicroServices/Business/Bussiness.Model/bin/Debug/net6.0/Business.EntityFrameworkCore.pdb
 MicroServices/Business/Bussiness.Model/obj/Debug/net6.0/Bussiness.Model.csproj.CopyComplete
+MicroServices/Business/Business.Common.Utility/obj/Business.Common.Utility.csproj.nuget.dgspec.json
+MicroServices/Business/Business.Common.Utility/obj/Business.Common.Utility.csproj.nuget.g.props
+MicroServices/Business/Business.Common.Utility/obj/Business.Common.Utility.csproj.nuget.g.targets
+MicroServices/Business/Business.Common.Utility/obj/project.assets.json
+MicroServices/Business/Business.Common.Utility/obj/project.nuget.cache
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.AssemblyInfo.cs
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.AssemblyInfoInputs.cache
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.assets.cache
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.csproj.AssemblyReference.cache
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.GeneratedMSBuildEditorConfig.editorconfig
+MicroServices/Business/Business.Common.Utility/obj/Debug/net6.0/Business.Common.Utility.GlobalUsings.g.cs

+ 9 - 0
MicroServices/Business/Business.Common.Utility/Business.Common.Utility.csproj

@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+</Project>

+ 176 - 0
MicroServices/Business/Business.Common.Utility/SnowFlake.cs

@@ -0,0 +1,176 @@
+using System.Reflection.PortableExecutable;
+
+namespace ApiDemo
+{
+    /// <summary>
+    /// 雪花算法生成id
+    /// </summary>
+    public class SnowFlake
+    {
+        /// <summary>
+        /// 机器id所占的位数
+        /// </summary>
+        private const int workerIdBits = 5;
+
+        /// <summary>
+        /// 数据表述id所占位数
+        /// </summary>
+        private const int datacenterIdBits = 5;
+
+        /// <summary>
+        /// 支持的最大机器id,结果是31
+        /// </summary>
+        private const long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+        /// <summary>
+        /// 支持的最大数据表示id,结果是31
+        /// </summary>
+        private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+        /// <summary>
+        /// 序列在id中所占的位数
+        /// </summary>
+        private const int sequenceBits = 12;
+
+        /// <summary>
+        /// 数据标识id向左移17位
+        /// </summary>
+        private const int datacenterIdShift = sequenceBits + workerIdBits;
+
+        /// <summary>
+        /// 机器ID向左移12位
+        /// </summary>
+        private const int workerIdShift = sequenceBits;
+
+        private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+        /// <summary>
+        /// 生成序列的掩码
+        /// </summary>
+        private const long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+        /// <summary>
+        /// 数据中心ID(0-31)
+        /// </summary>
+        public long DatacenterId { get; private set; }
+
+        /// <summary>
+        /// 工作机器ID(0-31)
+        /// </summary>
+        public long WorkerId { get; private set; }
+
+        /// <summary>
+        /// 毫秒内序列(0-4095)
+        /// </summary>
+        public long Sequence { get; private set; }
+
+        /// <summary>
+        /// 上次生成ID的时间戳
+        /// </summary>
+        public long LastTimestamp { get; private set; }
+
+        /// <summary>
+        /// 开始时间戳。首次使用前设置,否则无效,默认2010-1-1
+        /// </summary>
+        public DateTime StartTimestamp { get; set; } = new DateTime(2010,1,1);
+
+        static object syncRoot = new object();
+        static readonly Lazy<SnowFlake> snowflake = new(() => new SnowFlake(0L,0L));
+
+        /// <summary>
+        /// 默认金泰实例,WorkerId = 0,DatacenterId = 0
+        /// </summary>
+        public static SnowFlake Instance { get; } = snowflake.Value;
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="workerId">工作机器ID</param>
+        /// <param name="datacenterId">数据中心ID</param>
+        /// <exception cref="ArgumentOutOfRangeException"></exception>
+        public SnowFlake(long workerId,long datacenterId)
+        {
+            if (workerId > maxWorkerId || workerId < 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(workerId),$"不能大于{maxWorkerId}或小于0");
+            }
+            if (datacenterId > maxDatacenterId || datacenterId < 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(datacenterId), $"不能大于{maxDatacenterId}或小于0");
+            }
+            WorkerId = workerId;
+            DatacenterId = datacenterId;
+            Sequence = 0L;
+            LastTimestamp = -1L;
+        }
+
+        /// <summary>
+        /// 获取下一个ID
+        /// </summary>
+        /// <returns></returns>
+        public long NextId()
+        {
+            lock (syncRoot)
+            {
+                //获取当前时间戳
+                long timestamp = GetCurrentTimestamp();
+                if (timestamp > LastTimestamp)//时间戳改变,毫秒内序列重置
+                {
+                    Sequence = 0L;
+                }
+                else if (timestamp == LastTimestamp)//如果是同一时间生成的,则进行毫秒内序列
+                {
+                    Sequence = (Sequence + 1) & sequenceMask;
+                    if (Sequence == 0)//毫秒内序列溢出
+                    {
+                        timestamp = GetNextTimestamp(LastTimestamp);//阻塞到下一个毫秒,获取新的时间戳
+                    }
+                }
+                else//当前时间小于上一次ID生成的时间戳,证明系统时钟被回拨,此时需要做回拨处理
+                {
+                    Sequence = (Sequence + 1) & sequenceMask;
+                    if (Sequence > 0)
+                    {
+                        timestamp = LastTimestamp;//停留再最后一次时间戳上,等待系统时间追上后即完全度过了时钟回拨问题
+                    }
+                    else {
+                        timestamp = LastTimestamp + 1;//直接进位到下一个毫秒
+                    }
+                }
+                LastTimestamp = timestamp;//上次生成ID的时间戳
+
+                //移动并通过或运算拼到一起组成64位的ID
+                var id = (timestamp << timestampLeftShift)
+                        | (DatacenterId << datacenterIdShift)
+                        | (WorkerId << workerIdShift)
+                        | Sequence;
+                return id;
+            }
+        }
+
+        /// <summary>
+        /// 阻塞到下一个毫秒,直到获得新的时间戳
+        /// </summary>
+        /// <param name="lastTimestamp"></param>
+        /// <returns></returns>
+        private long GetNextTimestamp(long lastTimestamp)
+        {
+            //获取当前时间戳
+            long timestamp = GetCurrentTimestamp();
+            while (timestamp <= lastTimestamp)
+            { 
+                timestamp = GetCurrentTimestamp();
+            }
+            return timestamp;
+        }
+
+        /// <summary>
+        /// 获取当前时间戳
+        /// </summary>
+        /// <returns></returns>
+        private long GetCurrentTimestamp()
+        {
+            return (long)(DateTime.Now - StartTimestamp).TotalMilliseconds;
+        }
+    }
+}

+ 6 - 0
MicroServices/Business/Business.sln

@@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Business.Core", "Business.C
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bussiness.Model", "Bussiness.Model\Bussiness.Model.csproj", "{D9A37E35-A3BD-4A11-A3D8-571586EB2007}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Business.Common.Utility", "Business.Common.Utility\Business.Common.Utility.csproj", "{2E2BFBC4-49A8-4F15-8FDB-38235FF82FE4}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -63,6 +65,10 @@ Global
 		{D9A37E35-A3BD-4A11-A3D8-571586EB2007}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{D9A37E35-A3BD-4A11-A3D8-571586EB2007}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D9A37E35-A3BD-4A11-A3D8-571586EB2007}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2E2BFBC4-49A8-4F15-8FDB-38235FF82FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2E2BFBC4-49A8-4F15-8FDB-38235FF82FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2E2BFBC4-49A8-4F15-8FDB-38235FF82FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2E2BFBC4-49A8-4F15-8FDB-38235FF82FE4}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE