admin管理员组

文章数量:1037775

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

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

前言

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> ()

```

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

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

前言

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> ()

```

本文标签: osharp集成YitterIdGenerator并实现分布式ID