init
This commit is contained in:
26
Ocelot.Provider.Nacos/NacosClient/LoadBalance/ILBStrategy.cs
Normal file
26
Ocelot.Provider.Nacos/NacosClient/LoadBalance/ILBStrategy.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Nacos;
|
||||
using Nacos.V2.Naming.Dtos;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
public interface ILBStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// Strategy Name
|
||||
/// </summary>
|
||||
LBStrategyName Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get host
|
||||
/// </summary>
|
||||
/// <param name="list">host list</param>
|
||||
/// <returns>The Host</returns>
|
||||
Instance GetHost(List<Instance> list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
public enum LBStrategyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Weight Round Robin
|
||||
/// </summary>
|
||||
WeightRoundRobin,
|
||||
|
||||
/// <summary>
|
||||
/// Weight Random
|
||||
/// </summary>
|
||||
WeightRandom,
|
||||
|
||||
/// <summary>
|
||||
/// Ext1
|
||||
/// </summary>
|
||||
Ext1
|
||||
}
|
||||
}
|
||||
9
Ocelot.Provider.Nacos/NacosClient/LoadBalance/LbKv.cs
Normal file
9
Ocelot.Provider.Nacos/NacosClient/LoadBalance/LbKv.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
public class LbKv
|
||||
{
|
||||
public string InstanceId { get; set; }
|
||||
|
||||
public double Weight { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using Nacos;
|
||||
using Nacos.V2.Naming.Dtos;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
public class WeightRandomLBStrategy : ILBStrategy
|
||||
{
|
||||
public LBStrategyName Name => LBStrategyName.WeightRandom;
|
||||
|
||||
public Instance GetHost(List<Instance> list)
|
||||
{
|
||||
var dict = BuildScore(list);
|
||||
|
||||
Instance instance = null;
|
||||
|
||||
var rd = new Random().NextDouble();
|
||||
|
||||
foreach (var item in dict)
|
||||
{
|
||||
if (item.Value >= rd)
|
||||
{
|
||||
instance = list.FirstOrDefault(x => x.InstanceId.Equals(item.Key));
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
var arr = item.Key.Split("#");
|
||||
var ip = arr[0];
|
||||
int.TryParse(arr[1], out var port);
|
||||
var cluster = arr[2];
|
||||
|
||||
instance = list.First(x => x.Ip.Equals(ip) && x.Port == port && x.ClusterName.Equals(cluster));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Dictionary<string, double> BuildScore(List<Instance> list)
|
||||
{
|
||||
var dict = new Dictionary<string, double>();
|
||||
|
||||
// aliyun sae, the instanceid returns empty string
|
||||
// when the instanceid is empty, create a new one, but the group was missed.
|
||||
list.ForEach(x => { x.InstanceId = string.IsNullOrWhiteSpace(x.InstanceId) ? $"{x.Ip}#{x.Port}#{x.ClusterName}#{x.ServiceName}" : x.InstanceId; });
|
||||
|
||||
var tmp = list.Select(x => new LbKv
|
||||
{
|
||||
InstanceId = x.InstanceId,
|
||||
Weight = x.Weight
|
||||
}).GroupBy(x => x.InstanceId).Select(x => new LbKv
|
||||
{
|
||||
InstanceId = x.Key,
|
||||
Weight = x.Max(y => y.Weight)
|
||||
}).ToList();
|
||||
|
||||
var total = tmp.Sum(x => x.Weight);
|
||||
var cur = 0d;
|
||||
|
||||
foreach (var item in tmp)
|
||||
{
|
||||
cur += item.Weight;
|
||||
dict.TryAdd(item.InstanceId, cur / total);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Nacos;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nacos.V2.Naming.Dtos;
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
public class WeightRoundRobinLBStrategy : ILBStrategy
|
||||
{
|
||||
public LBStrategyName Name => LBStrategyName.WeightRoundRobin;
|
||||
|
||||
private int _pos;
|
||||
|
||||
private static object obj = new object();
|
||||
|
||||
public Instance GetHost(List<Instance> list)
|
||||
{
|
||||
// aliyun sae, the instanceid returns empty string
|
||||
// when the instanceid is empty, create a new one, but the group was missed.
|
||||
list.ForEach(x => { x.InstanceId = string.IsNullOrWhiteSpace(x.InstanceId) ? $"{x.Ip}#{x.Port}#{x.ClusterName}#{x.ServiceName}" : x.InstanceId; });
|
||||
|
||||
var tmp = list.Select(x => new LbKv
|
||||
{
|
||||
InstanceId = x.InstanceId,
|
||||
Weight = x.Weight
|
||||
}).GroupBy(x => x.InstanceId).Select(x => new LbKv
|
||||
{
|
||||
InstanceId = x.Key,
|
||||
Weight = x.Max(y => y.Weight)
|
||||
}).ToList();
|
||||
|
||||
// <instanceid, weight>
|
||||
var dic = tmp.ToDictionary(k => k.InstanceId, v => (int)v.Weight);
|
||||
|
||||
var srcInstanceIdList = dic.Keys.ToList();
|
||||
var tagInstanceIdList = new List<string>();
|
||||
|
||||
foreach (var item in srcInstanceIdList)
|
||||
{
|
||||
dic.TryGetValue(item, out var weight);
|
||||
|
||||
for (int i = 0; i < weight; i++)
|
||||
tagInstanceIdList.Add(item);
|
||||
}
|
||||
|
||||
var instanceId = string.Empty;
|
||||
|
||||
lock (obj)
|
||||
{
|
||||
if (_pos >= tagInstanceIdList.Count)
|
||||
_pos = 0;
|
||||
|
||||
instanceId = tagInstanceIdList[_pos];
|
||||
_pos++;
|
||||
}
|
||||
|
||||
var instance = list.FirstOrDefault(x => x.InstanceId.Equals(instanceId));
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
var arr = instanceId.Split("#");
|
||||
var ip = arr[0];
|
||||
int.TryParse(arr[1], out var port);
|
||||
var cluster = arr[2];
|
||||
|
||||
instance = list.First(x => x.Ip.Equals(ip) && x.Port == port && x.ClusterName.Equals(cluster));
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
145
Ocelot.Provider.Nacos/NacosClient/UriTool.cs
Normal file
145
Ocelot.Provider.Nacos/NacosClient/UriTool.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
namespace Ocelot.Provider.Nacos.NacosClient
|
||||
{
|
||||
internal static class UriTool
|
||||
{
|
||||
public static IEnumerable<Uri> GetUri(IFeatureCollection features, string ip, int port, string preferredNetworks)
|
||||
{
|
||||
var splitChars = new char[] { ',', ';' };
|
||||
var appPort = port <= 0 ? 80 : port;
|
||||
|
||||
// 1. config
|
||||
if (!string.IsNullOrWhiteSpace(ip))
|
||||
{
|
||||
// it seems that nacos don't return the scheme
|
||||
// so here use http only.
|
||||
return new List<Uri> { new Uri($"http://{ip}:{appPort}") };
|
||||
}
|
||||
|
||||
// 1.1. Ip is null && Port has value
|
||||
if (string.IsNullOrWhiteSpace(ip) && appPort != 80)
|
||||
{
|
||||
return new List<Uri> { new Uri($"http://{GetCurrentIp(preferredNetworks)}:{appPort}") };
|
||||
}
|
||||
|
||||
var address = string.Empty;
|
||||
|
||||
// 2. IServerAddressesFeature
|
||||
if (features != null)
|
||||
{
|
||||
var addresses = features.Get<IServerAddressesFeature>();
|
||||
var addressCollection = addresses?.Addresses;
|
||||
|
||||
if (addressCollection != null && addressCollection.Any())
|
||||
{
|
||||
var uris = new List<Uri>();
|
||||
foreach (var item in addressCollection)
|
||||
{
|
||||
var url = ReplaceAddress(item, preferredNetworks);
|
||||
uris.Add(new Uri(url));
|
||||
}
|
||||
|
||||
return uris;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ASPNETCORE_URLS
|
||||
address = Environment.GetEnvironmentVariable("ASPNETCORE_URLS");
|
||||
if (!string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
var url = ReplaceAddress(address, preferredNetworks);
|
||||
|
||||
return url.Split(splitChars).Select(x => new Uri(x));
|
||||
}
|
||||
|
||||
// 4. --urls
|
||||
var cmdArgs = Environment.GetCommandLineArgs();
|
||||
if (cmdArgs != null && cmdArgs.Any())
|
||||
{
|
||||
var cmd = cmdArgs.FirstOrDefault(x => x.StartsWith("--urls", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(cmd))
|
||||
{
|
||||
address = cmd.Split('=')[1];
|
||||
|
||||
var url = ReplaceAddress(address, preferredNetworks);
|
||||
|
||||
return url.Split(splitChars).Select(x => new Uri(x));
|
||||
}
|
||||
}
|
||||
|
||||
// 5. current ip address third
|
||||
address = $"http://{GetCurrentIp(preferredNetworks)}:{appPort}";
|
||||
|
||||
return new List<Uri> { new Uri(address) };
|
||||
}
|
||||
|
||||
private static string ReplaceAddress(string address, string preferredNetworks)
|
||||
{
|
||||
var ip = GetCurrentIp(preferredNetworks);
|
||||
|
||||
if (address.Contains("*"))
|
||||
{
|
||||
address = address.Replace("*", ip);
|
||||
}
|
||||
else if (address.Contains("+"))
|
||||
{
|
||||
address = address.Replace("+", ip);
|
||||
}
|
||||
else if (address.Contains("localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
address = address.Replace("localhost", ip, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else if (address.Contains("0.0.0.0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
address = address.Replace("0.0.0.0", ip, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
private static string GetCurrentIp(string preferredNetworks)
|
||||
{
|
||||
var instanceIp = "127.0.0.1";
|
||||
|
||||
try
|
||||
{
|
||||
// 获取可用网卡
|
||||
var nics = NetworkInterface.GetAllNetworkInterfaces()?.Where(network => network.OperationalStatus == OperationalStatus.Up);
|
||||
|
||||
// 获取所有可用网卡IP信息
|
||||
var ipCollection = nics?.Select(x => x.GetIPProperties())?.SelectMany(x => x.UnicastAddresses);
|
||||
|
||||
foreach (var ipadd in ipCollection)
|
||||
{
|
||||
if (!IPAddress.IsLoopback(ipadd.Address) && ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
if (string.IsNullOrEmpty(preferredNetworks))
|
||||
{
|
||||
instanceIp = ipadd.Address.ToString();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ipadd.Address.ToString().StartsWith(preferredNetworks)) continue;
|
||||
instanceIp = ipadd.Address.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return instanceIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
96
Ocelot.Provider.Nacos/NacosClient/V2/NacosAspNetOptions.cs
Normal file
96
Ocelot.Provider.Nacos/NacosClient/V2/NacosAspNetOptions.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using Nacos.V2;
|
||||
using Nacos.V2.Common;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ocelot.Provider.Nacos.NacosClient.V2
|
||||
{
|
||||
public class NacosAspNetOptions : NacosSdkOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// the name of the service.
|
||||
/// </summary>
|
||||
public string ServiceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the name of the group.
|
||||
/// </summary>
|
||||
public string GroupName { get; set; } = Constants.DEFAULT_GROUP;
|
||||
|
||||
/// <summary>
|
||||
/// the name of the cluster.
|
||||
/// </summary>
|
||||
/// <value>The name of the cluster.</value>
|
||||
public string ClusterName { get; set; } = Constants.DEFAULT_CLUSTER_NAME;
|
||||
|
||||
/// <summary>
|
||||
/// the ip of this instance
|
||||
/// </summary>
|
||||
public string Ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Select an IP that matches the prefix as the service registration IP
|
||||
/// like the config of spring.cloud.inetutils.preferred-networks
|
||||
/// </summary>
|
||||
public string PreferredNetworks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the port of this instance
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the weight of this instance.
|
||||
/// </summary>
|
||||
public double Weight { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// if you just want to subscribe, but don't want to register your service, set it to false.
|
||||
/// </summary>
|
||||
public bool RegisterEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// the metadata of this instance
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Metadata { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// If instance is enabled to accept request. The default value is true.
|
||||
/// </summary>
|
||||
public bool InstanceEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// If instance is ephemeral.The default value is true.
|
||||
/// </summary>
|
||||
public bool Ephemeral { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// whether your service is a https service.
|
||||
/// </summary>
|
||||
public bool Secure { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Load Balance Strategy
|
||||
/// </summary>
|
||||
public string LBStrategy { get; set; } = LBStrategyName.WeightRandom.ToString();
|
||||
|
||||
public NacosSdkOptions BuildSdkOptions()
|
||||
{
|
||||
return new NacosSdkOptions
|
||||
{
|
||||
AccessKey = this.AccessKey,
|
||||
ConfigUseRpc = this.ConfigUseRpc,
|
||||
ContextPath = this.ContextPath,
|
||||
DefaultTimeOut = this.DefaultTimeOut,
|
||||
EndPoint = this.EndPoint,
|
||||
ListenInterval = this.ListenInterval,
|
||||
Namespace = this.Namespace,
|
||||
NamingLoadCacheAtStart = this.NamingLoadCacheAtStart,
|
||||
NamingUseRpc = this.NamingUseRpc,
|
||||
Password = this.Password,
|
||||
SecretKey = this.SecretKey,
|
||||
ServerAddresses = this.ServerAddresses,
|
||||
UserName = this.UserName,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
127
Ocelot.Provider.Nacos/NacosClient/V2/RegSvcBgTask.cs
Normal file
127
Ocelot.Provider.Nacos/NacosClient/V2/RegSvcBgTask.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Nacos.V2;
|
||||
using Nacos.V2.Naming.Core;
|
||||
using Nacos.V2.Naming.Dtos;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Provider.Nacos.NacosClient.V2
|
||||
{
|
||||
public class RegSvcBgTask
|
||||
{
|
||||
private static readonly string MetadataNetVersion = "DOTNET_VERSION";
|
||||
private static readonly string MetadataHostOs = "HOST_OS";
|
||||
private static readonly string MetadataSecure = "secure";
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly INacosNamingService _svc;
|
||||
private readonly IFeatureCollection _features;
|
||||
private NacosAspNetOptions _options;
|
||||
|
||||
private IEnumerable<Uri> uris = null;
|
||||
|
||||
public RegSvcBgTask(
|
||||
ILoggerFactory loggerFactory,
|
||||
INacosNamingService svc,
|
||||
IServer server,
|
||||
IOptionsMonitor<NacosAspNetOptions> optionsAccs)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger<RegSvcBgTask>();
|
||||
_svc = svc;
|
||||
_options = optionsAccs.CurrentValue;
|
||||
_features = server.Features;
|
||||
}
|
||||
|
||||
public async Task StartAsync()
|
||||
{
|
||||
if (!_options.RegisterEnabled)
|
||||
{
|
||||
_logger.LogInformation("setting RegisterEnabled to false, will not register to nacos");
|
||||
return;
|
||||
}
|
||||
|
||||
uris = UriTool.GetUri(_features, _options.Ip, _options.Port, _options.PreferredNetworks);
|
||||
|
||||
var metadata = new Dictionary<string, string>()
|
||||
{
|
||||
{ PreservedMetadataKeys.REGISTER_SOURCE, $"ASPNET_CORE" },
|
||||
{ MetadataNetVersion, Environment.Version.ToString() },
|
||||
{ MetadataHostOs, Environment.OSVersion.ToString() },
|
||||
};
|
||||
|
||||
if (_options.Secure) metadata[MetadataSecure] = "true";
|
||||
|
||||
foreach (var item in _options.Metadata)
|
||||
{
|
||||
if (!metadata.ContainsKey(item.Key))
|
||||
{
|
||||
metadata.TryAdd(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var uri in uris)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
var instance = new Instance
|
||||
{
|
||||
Ephemeral = _options.Ephemeral,
|
||||
ServiceName = _options.ServiceName,
|
||||
ClusterName = _options.ClusterName,
|
||||
Enabled = _options.InstanceEnabled,
|
||||
Healthy = true,
|
||||
Ip = uri.Host,
|
||||
Port = uri.Port,
|
||||
Weight = _options.Weight,
|
||||
Metadata = metadata,
|
||||
InstanceId = ""
|
||||
};
|
||||
|
||||
_logger.LogInformation("register instance to nacos server, 【{0}】", instance);
|
||||
|
||||
await _svc.RegisterInstance(_options.ServiceName, _options.GroupName, instance);
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "register instance error, count = {0}", i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StopAsync()
|
||||
{
|
||||
if (_options.RegisterEnabled)
|
||||
{
|
||||
_logger.LogWarning("deregister instance from nacos server, serviceName={0}", _options.ServiceName);
|
||||
|
||||
foreach (var uri in uris)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogWarning("begin to remove instance");
|
||||
await _svc.DeregisterInstance(_options.ServiceName, _options.GroupName, uri.Host, uri.Port, _options.ClusterName);
|
||||
_logger.LogWarning("removed instance");
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "deregister instance error, count = {0}", i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Nacos.V2.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.Provider.Nacos.NacosClient.V2
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Add Nacos AspNet. This will register and de-register instance automatically.
|
||||
/// Mainly for nacos server 2.x
|
||||
/// </summary>
|
||||
/// <param name="services">services.</param>
|
||||
/// <param name="configuration">configuration</param>
|
||||
/// <returns>IServiceCollection</returns>
|
||||
public static IServiceCollection AddNacosAspNet(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.Configure<NacosAspNetOptions>(configuration.GetSection("nacos"));
|
||||
services.AddNacosV2Naming(configuration);
|
||||
services.AddSingleton<RegSvcBgTask>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Nacos AspNet. This will register and de-register instance automatically.
|
||||
/// Mainly for nacos server 2.x
|
||||
/// </summary>
|
||||
/// <param name="services">services</param>
|
||||
/// <param name="optionsAccs">optionsAccs</param>
|
||||
/// <returns>IServiceCollection</returns>
|
||||
public static IServiceCollection AddNacosAspNet(this IServiceCollection services, Action<NacosAspNetOptions> optionsAccs)
|
||||
{
|
||||
services.Configure(optionsAccs);
|
||||
|
||||
var options = new NacosAspNetOptions();
|
||||
optionsAccs.Invoke(options);
|
||||
services.AddNacosV2Naming(x => options.BuildSdkOptions());
|
||||
services.AddSingleton<RegSvcBgTask>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
public static async Task<IApplicationBuilder> UseNacosAspNet(this IApplicationBuilder app, IHostApplicationLifetime lifetime)
|
||||
{
|
||||
RegSvcBgTask regSvcBgTask = app.ApplicationServices.GetRequiredService<RegSvcBgTask>();
|
||||
await regSvcBgTask.StartAsync();
|
||||
lifetime.ApplicationStopping.Register(async () => {
|
||||
await regSvcBgTask.StopAsync();
|
||||
});
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user