基于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); } }
关注开源
国内最早的Orleans群--174511582,欢迎大家加入