一个简单唯一ID生成规则

在很多业务场景下需要由生成一个唯一ID,而其唯一性是针对业务上所有服务器。其实生成唯一ID的方式有很多,数据库自增或序列,提供一个生成服务和用GUID。以下介绍一个64位的唯一ID生成规则,而它并不需要依赖任何服务。

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;
            }
        }
    }

转载于:https://my.oschina.net/ikende/blog/202618

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值