Witte

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

基于Orleans的分布式Id生成方案,因Orleans的单实例、单线程模型,让这种实现变的简单,贴出一种实现,欢迎大家提出意见

public interface ISequenceNoGenerator : Orleans.IGrainWithIntegerKey
{
   Task<Immutable<string>> GetNext();
}
public class SequenceNoGenerator : Orleans.Grain, ISequenceNoGenerator
 {
     private const int MaxSeed = 99999;
     private int _seed = 0;
     private int _currentSecondCounter = 0;
     Task<Immutable<string>> ISequenceNoGenerator.GetNext()
     {
         var oldCounter = this._currentSecondCounter;

         while (true)
         {
             this.UpdateCurrentTimestamp();

             if (oldCounter != this._currentSecondCounter)
                 this._seed = 1;
             else
             {
                 ++this._seed;
             }

             if (this._seed > MaxSeed) Task.Delay(100);
             else break;
         }

         var seq = DateTime.Now.ToString("yyyyMMdd") + this._currentSecondCounter.ToString() + this._seed.ToString();
         return Task.FromResult(seq.AsImmutable());
     }

     public override Task OnActivateAsync()
     {
         //延迟1秒启动,防止Activation在某个机器上崩溃后,在集群中其它host上启动时,sequenceNo在同一秒出现重复
          Task.Delay(1000);

         return base.OnActivateAsync();
     }

     private void UpdateCurrentTimestamp()
     {
         var currentTime = DateTime.Now;
         var currentDayStart = Convert.ToDateTime(currentTime.ToShortDateString());
         this._currentSecondCounter = (int)(new TimeSpan(currentTime.Ticks - currentDayStart.Ticks).TotalSeconds);
     }
 }
posted on 2015-02-16 17:30  Witte  阅读(2548)  评论(5编辑  收藏  举报