RefreshYarp.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using Common;
  2. using Infrastructure;
  3. using Nacos.V2;
  4. using Nacos.V2.DependencyInjection;
  5. using Yarp.ReverseProxy.Configuration;
  6. public class RefreshYarp : BackgroundService
  7. {
  8. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  9. {
  10. while (!stoppingToken.IsCancellationRequested)
  11. {
  12. try
  13. {
  14. // 例如后台定时任务 / Nacos 监听回调里
  15. var provider = App.ServiceProvider.GetRequiredService<InMemoryConfigProvider>();
  16. var clusters = new List<ClusterConfig>();
  17. var routes = new List<RouteConfig>();
  18. var services = new ServiceCollection();
  19. services.AddNacosV2Naming(x =>
  20. {
  21. InternalApp.Configuration.GetSection("NacosConfig").Bind(x);
  22. });
  23. var sp = services.BuildServiceProvider();
  24. var naming = sp.GetRequiredService<INacosNamingService>();
  25. var options = App.OptionsSetting;
  26. foreach(var service in options.Services)
  27. {
  28. string serviceName = service.Name;
  29. var list = await naming.GetAllInstances(serviceName, "DEFAULT");
  30. var healthy = list.Where(h => h.Healthy && h.Enabled).ToList();
  31. if (healthy.Count > 0)
  32. {
  33. var dests = healthy.ToDictionary(
  34. k => $"{k.Ip}:{k.Port}",
  35. v => new DestinationConfig { Address = $"http://{v.Ip}:{v.Port}" });
  36. Console.WriteLine("serviceHosts---" + Newtonsoft.Json.JsonConvert.SerializeObject(dests));
  37. string ClusterId = serviceName + "-cluster";
  38. string RouteId = serviceName + "-route";
  39. if(!clusters.Any(m => m.ClusterId == ClusterId))
  40. {
  41. clusters.Add(new ClusterConfig
  42. {
  43. ClusterId = ClusterId,
  44. Destinations = dests
  45. });
  46. }
  47. else
  48. {
  49. RouteId += "-" + routes.Count(m => m.ClusterId == ClusterId);
  50. }
  51. routes.Add(new RouteConfig
  52. {
  53. RouteId = RouteId,
  54. ClusterId = ClusterId,
  55. Match = new RouteMatch { Path = service.Path }
  56. });
  57. }
  58. }
  59. // 一键生效,不需要重启
  60. provider.Update(routes, clusters);
  61. }
  62. catch(Exception ex)
  63. {
  64. Utils.WriteLog(ex.ToString(), "实时同步nacos服务数据异常");
  65. }
  66. await Task.Delay(10000, stoppingToken);
  67. }
  68. }
  69. }