Snowflake算法生成Id
網(wǎng)上大部分C#寫的都有點(diǎn)亂糟糟,我簡化了一下。這個(gè)算法總體思想是生成一個(gè)64位整數(shù),前42位放從前某特定時(shí)間點(diǎn)到當(dāng)前時(shí)間的毫秒數(shù),中間10位放生成id的機(jī)器的唯一編碼,后12位放順序號(hào)(如果同一毫秒內(nèi)生成多次,此順序號(hào)可避免產(chǎn)生重復(fù)id)
using System;
namespace xxx
{
/// <summary>
/// Id 生成類
/// </summary>
class Snowflake
{
private const string LOCK_OBJ = "76003AEB-E3F9-460A-BD31-D9AE9E7684C0";
private const int MACHINE_BIT_SIZE = 10; // 機(jī)器編號(hào)長度10位
private const int SEQUENCE_BIT_SIZE = 12; // 序號(hào)長度12位
private static Snowflake _snowflake;
private long _machineNumber; // 機(jī)器序號(hào)
private long _timestamp; // 時(shí)間戳
private long _sequence; // 序號(hào)
private Snowflake() { }
/// <summary>
/// 設(shè)置機(jī)器序號(hào)
/// </summary>
public int MachineNumber
{
set { _machineNumber = value; }
}
/// <summary>
/// 得到一個(gè)實(shí)例
/// </summary>
/// <returns></returns>
public static Snowflake GetInstance()
{
if (_snowflake == null)
{
lock (LOCK_OBJ)
{
if (_snowflake == null)
{
_snowflake = new Snowflake();
}
}
}
return _snowflake;
}
/// <summary>
/// 產(chǎn)生一個(gè)id,由時(shí)間戳、機(jī)器編碼、順序號(hào)組成
/// </summary>
/// <returns></returns>
public long GenerateId(Func<DateTime> GetTime)
{
lock (LOCK_OBJ)
{
if (_machineNumber > (-1L ^ -1L << MACHINE_BIT_SIZE))
{
throw new ArgumentException("機(jī)器編號(hào)超出最大值");
}
long timestamp = GetTimestamp(GetTime());
if (timestamp < _timestamp)
{
throw new ArgumentException("時(shí)間戳錯(cuò)誤");
}
if (timestamp == _timestamp)
{
_sequence++;
if (_sequence > (-1L ^ -1L << SEQUENCE_BIT_SIZE))
{
while (true) // 序號(hào)已用完,等下一毫秒
{
timestamp = GetTimestamp(GetTime());
if (timestamp > _timestamp)
{
_sequence = 0;
break;
}
}
}
}
else
{
_sequence = 0;
}
long id = timestamp << (MACHINE_BIT_SIZE + SEQUENCE_BIT_SIZE)
| _machineNumber << SEQUENCE_BIT_SIZE
| _sequence;
_timestamp = timestamp;
return id;
}
}
// 當(dāng)前時(shí)間戳
private long GetTimestamp(DateTime now)
{
return (long)(now - new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
}
}
}
調(diào)用:
using System;
namespace xxx
{
public class IdGenerator
{
/// <summary>
/// 生成Id
/// </summary>
/// <returns></returns>
public static long GenerateId()
{
Snowflake sf = Snowflake.GetInstance();
sf.MachineNumber = YourGetMachineNumberFunction();
long id = sf.GenerateId(GetTime);
return id;
}
private static DateTime GetTime()
{
return YourGetNowTimeFunction();
}
}
}
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處

浙公網(wǎng)安備 33010602011771號(hào)