This commit is contained in:
cjd
2025-11-04 21:09:16 +08:00
parent 8260e293c7
commit bb90a020dc
592 changed files with 61749 additions and 27 deletions

View 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,
};
}
}
}

View 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);
}
}
}
}
}
}
}

View File

@@ -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;
}
}
}