ID生成规则
服务之间的唯一性,为了实现这一点必须有一个标识来区分不同服务器之间的差异值。开始打算采用配置一个服务器标识来处理,后来发现应用起来存在配置不方便;为了实现这一目标采用了ipaddrsss存储的后两位,经过思考对于一个应用来说其不同服务器部署的IP段后两位不可能存在重复,因此这样可以很好地分离出不同服务器生成的ID值区间。不过着服务部署的更改以后IP分配有可能发生变化,所以ID的生成还依赖于服务器时间,具体规则如下:
缺点由于存储位数不足,所以每个服务器实例每秒只能生成6W多个ID,不过这个量已经可以满足大部应用的需要了.
ID生成代码
public class IDCreater
{
public IDCreater()
{
System.Net.IPAddress ip = null;
System.Net.IPAddress[] ips = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName());
foreach (System.Net.IPAddress item in ips)
{
if (!item.IsIPv6LinkLocal)
{
ip = item;
break;
}
}
byte[] data = ip.GetAddressBytes();
mIPValue = BitConverter.ToUInt32(data, 0);
mIPValue = mIPValue << 16;
mIPValue = mIPValue >> 16;
mTick = Environment.TickCount;
mSeconds = (uint)Convert.ToUInt32((DateTime.Now - mDefaultTime).TotalSeconds);
}
private DateTime mDefaultTime = DateTime.Parse("2014-1-1");
private uint mSeconds;
private int mTick;
private uint mIPValue;
private uint mSequence = 1;
private uint GetSeconds()
{
mSequence++;
if (mSequence >= ushort.MaxValue)
{
uint s = (uint)Convert.ToUInt32((DateTime.Now - mDefaultTime).TotalSeconds);
if(s== mSeconds)
throw new Exception("sequence overflow");
mSeconds = s;
mSequence = 1;
}
return mSeconds;
}
public ulong Next()
{
lock (this)
{
ulong result=0;
ulong s = GetSeconds();
result = result | (s << 32);
result = result | (mSequence<<16);
result = result | mIPValue;
return result;
}
}
}