首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >osharp集成Yitter.IdGenerator并实现分布式ID

osharp集成Yitter.IdGenerator并实现分布式ID

原创
作者头像
吴晓阳
发布2025-03-14 13:05:12
发布2025-03-14 13:05:12
1100
举报

# osharp集成Yitter.IdGenerator并实现分布式ID

前言

osharp是什么?请看[https://github.com/dotnetcore/osharp](https://github.com/dotnetcore/osharp)

安装Yitter.IdGenerator

nuget安装Yitter.IdGenerator包

实现IKeyGenerator<long>

``` C#

using System;

using Microsoft.Extensions.Options;

using OSharp.Entity.KeyGenerate;

using OSharp.Data.Snows;

using Yitter.IdGenerator;

using IdGeneratorOptions = Yitter.IdGenerator.IdGeneratorOptions;

namespace Liuliu.Demo.Web.Startups.Yitter

{

public class YitterSnowKeyGenerator : IKeyGenerator<long>

{

public YitterSnowKeyGenerator()

{

}

public long Create()

{

return YitIdHelper.NextId();

}

}

}

```

## 实现YitterIdGeneratorPack

``` C#

using System.ComponentModel;

using OSharp.Hosting.Identity.Entities;

using OSharp.Hosting.MultiTenancy;

using Microsoft.Extensions.DependencyInjection.Extensions;

using OSharp.Authorization;

using OSharp.Authorization.Modules;

using OSharp.Caching;

using OSharp.Core.Packs;

using OSharp.Core.Systems;

using OSharp.Entity;

using OSharp.Identity;

using Yitter.IdGenerator;

using Liuliu.Demo.Web.Startups.Yitter;

using OSharp.Entity.KeyGenerate;

using System.Configuration;

using Microsoft.Extensions.Options;

using OSharp.Exceptions;

using Microsoft.Extensions.Caching.Distributed;

using Microsoft.DotNet.Scaffolding.Shared;

namespace Liuliu.Demo.Web.Startups

{

[DependsOnPacks(typeof(OsharpCorePack))]

public class YitterIdGeneratorPack : OsharpPack

{

private const string MainLockName = "sys_idGen:workerId:lock";

private const string MainValueKey = "sys_idGen:workerId:value";

public YitterIdGeneratorPack()

{

}

public override PackLevel Level => PackLevel.Framework;

public override IServiceCollection AddServices(IServiceCollection services)

{

IConfiguration configuration = services.GetConfiguration();

services.Configure<IdGeneratorOptions>(configuration.GetSection("IdGeneratorOptions"));

services.Replace<IKeyGenerator<long>, YitterSnowKeyGenerator>(ServiceLifetime.Singleton);

return services;

}

override public void UsePack(IServiceProvider provider)

{

var _options = provider.GetRequiredService<IOptions<IdGeneratorOptions>>().Value;

var _logger = provider.GetRequiredService<ILogger<YitterIdGeneratorPack>>();

var workerId = GetWorkerId(provider, _options);

var options = new IdGeneratorOptions

{

Method = _options.Method,

BaseTime = _options.BaseTime,

WorkerId = workerId,

WorkerIdBitLength = _options.WorkerIdBitLength,

SeqBitLength = _options.SeqBitLength,

MaxSeqNumber = _options.MaxSeqNumber,

MinSeqNumber = _options.MinSeqNumber,

TopOverCostCount = _options.TopOverCostCount

};

_logger.LogInformation($"Yitter.IdGenerator已配置,WorkerId: {workerId}");

YitIdHelper.SetIdGenerator(options);

}

private ushort GetWorkerId(IServiceProvider provider,IdGeneratorOptions options)

{

var lockName = $"{MainLockName}";

var valueKey = $"{MainValueKey}";

var minWorkId = 0;

var maxWorkId = (int)Math.Pow(2, (double)options.WorkerIdBitLength);

var cache = provider.GetRequiredService<IDistributedCache>();

var _logger = provider.GetRequiredService<ILogger<YitterIdGeneratorPack>>();

long workId = -1;

var tempWorkIds = Enumerable.Range(minWorkId, maxWorkId).Select(id => id.ToString()).ToList();

try

{

string workIdKey = "";

foreach (var item in tempWorkIds)

{

var workIdStr = item;

workIdKey = $"{valueKey}:{workIdStr}";

var exist = cache.Get<bool>(workIdKey);

if (exist)

{

workIdKey = "";

continue;

}

_logger.LogInformation($"############ 当前应用雪花WorkId:【{workIdStr}】############");

workId = long.Parse(workIdStr);

if (workId < minWorkId || workId > maxWorkId)

continue;

// 设置雪花Id算法机器码

YitIdHelper.SetIdGenerator(new IdGeneratorOptions

{

WorkerId = (ushort)workId,

WorkerIdBitLength = options.WorkerIdBitLength,

SeqBitLength = options.SeqBitLength

});

var cacheOptions = new DistributedCacheEntryOptions

{

AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60)

};

cache.Set(workIdKey, true, cacheOptions);

break;

}

if (string.IsNullOrWhiteSpace(workIdKey)) throw new OsharpException("未设置有效的机器码,启动失败");

// 开一个任务设置当前workId过期时间

Task.Run(() =>

{

while (true)

{

var cacheOptions = new DistributedCacheEntryOptions

{

AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60)

};

cache.Set(workIdKey, true, cacheOptions);

Thread.Sleep(10000);

}

});

}

catch (Exception ex)

{

throw new OsharpException($"{ex.Message};{ex.StackTrace};{ex.StackTrace}");

}

finally

{

}

if(workId < minWorkId || workId >= maxWorkId) throw new OsharpException("未设置有效的机器码,启动失败");

return (ushort)workId;

}

}

}

```

appsettings.Development.json加配置信息

``` json

"IdGeneratorOptions": {

"Method": 1,

"BaseTime": "2025-01-01T00:00:00Z",

"WorkerId": 2,

"WorkerIdBitLength": 6,

"SeqBitLength": 6,

"MaxSeqNumber": 0,

"MinSeqNumber": 5,

"TopOverCostCount": 2000

}

```

Startup.cs加载YitterIdGeneratorPack

``` C#

.AddPack<YitterIdGeneratorPack> ()

```

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档