.NET 反向代理 YARP 自定义配置提供程序(Configuration Providers) ...

饭宝  金牌会员 | 2022-9-25 01:29:54 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 905|帖子 905|积分 2715

介绍

  基本 Yarp 示例显示从 appsettings.json 加载的代理配置。相反,代理配置可以从您选择的源以编程方式加载。您可以通过提供几个实现 IProxyConfigProvider 和 IProxyConfig 的类来做到这一点。
  可以使用配置过滤器在加载序列期间修改配置。
结构

  IProxyConfigProvider 有一个方法应该返回一个 IProxyConfig 实例。 IProxyConfig 具有当前路由和集群的列表,以及在此信息过期并应重新加载时通知代理,这将导致再次调用(GetConfig()IChangeTokenGetConfig())
路线

  路由部分是命名路由的无序集合。路由包含匹配项及其相关配置。一条路线至少需要以下字段:
  RouteId - 一个唯一的名称
  ClusterId - 指集群部分中的条目名称。
  Match - 包含 Hosts 数组或 Path 模式字符串。 Path 是一个 ASP.NET Core 路由模板,可以按照此处的说明进行定义。
  可以在每个路由条目上配置标头、授权、CORS 和其他基于路由的策略。
  代理将应用给定的匹配条件和策略,然后将请求传递给指定的集群。
集群

  集群部分是命名集群的无序集合。集群主要包含命名目的地及其地址的集合,其中任何一个都被认为能够处理给定路由的请求。代理将根据路由和集群配置处理请求以选择目的地。
生命周期

启动

  应该在 DI 容器中注册为单例。启动时,代理将解析此实例并调用 .在第一次调用时,提供者可以选择:IProxyConfigProviderGetConfig()
  如果提供者出于任何原因无法生成有效的代理配置,则抛出异常。这将阻止应用程序启动。
  在加载配置时同步阻塞。这将阻止应用程序启动,直到有效的路线数据可用。
  或者,它可以选择在后台加载配置时返回一个空实例。提供者将需要在配置可用时触发(IProxyConfigIChangeToken)
  代理将验证给定的配置,如果它无效,将引发异常,阻止应用程序启动。提供者可以通过使用 IConfigValidator 来预先验证路由和集群并采取它认为适当的任何操作(例如排除无效条目)来避免这种情况。
原子性

  提供给代理的配置对象和集合应该是只读的,一旦通过 .GetConfig() 传递给代理就不能修改
重新加载

  如果支持,一旦代理处理了初始配置集,它将使用此令牌注册回调。如果提供者不支持回调,则每 5 分钟轮询一次(IChangeTokenActiveChangeCallbacksHasChanged)
  1、当提供者想要为代理提供新配置时,它应该:
  (1)在后台加载该配置。
    a. 路由和集群对象是不可变的,因此必须为任何新数据创建新实例。
    b. 可以重新使用未更改的路由和集群的对象,或者可以创建新的实例 - 将通过区分它们来检测更改。
  (2)可选地使用 IConfigValidator 验证配置,然后才从先前的实例发出新数据可用的信号。代理将再次调用以检索新数据(IChangeTokenIProxyConfigGetConfig())
  2、重新加载配置与第一次配置加载时存在重要差异。
  (1)新配置将与当前配置不同,并且只会更新修改后的路由或集群。更新将自动应用,并且只会影响新请求,而不影响当前正在进行的请求。
  (2)重新加载过程中的任何错误都将被记录并抑制。应用程序将继续使用上次已知的正确配置。
  (3)如果抛出代理将无法监听未来的变化,因为 s 是一次性的(GetConfig()IChangeToken)
  验证并应用新配置后,代理将使用新的 .请注意,如果连续发出多次重新加载信号,代理可能会跳过一些并在准备好后立即加载下一个可用配置。每个都包含完整的配置状态,因此不会丢失任何内容(IChangeTokenIProxyConfig)
多个配置源

  从 1.1 开始,YARP 支持从多个来源加载代理配置。 多个可以注册为单例服务,所有将被解析和组合。 源可以是相同或不同的类型,例如 IConfiguration 或 InMemory。 路由可以引用其他来源的集群。 请注意,不支持为给定路由或集群合并来自不同来源的部分配置(IProxyConfigProvider)
  1. services.AddReverseProxy()
  2.         .LoadFromConfig(Configuration.GetSection("ReverseProxy1"))
  3.         .LoadFromConfig(Configuration.GetSection("ReverseProxy2"));
复制代码
或者
  1. services.AddReverseProxy()
  2.         .LoadFromMemory(routes, clusters)
  3.         .LoadFromConfig(Configuration.GetSection("ReverseProxy"));
复制代码
Example

  以下是手动加载路由和集群的示例(IProxyConfigProvider)
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using Microsoft.Extensions.Primitives;
  4. using Yarp.ReverseProxy.Configuration;
  5. namespace Microsoft.Extensions.DependencyInjection
  6. {
  7.     public static class InMemoryConfigProviderExtensions
  8.     {
  9.         public static IReverseProxyBuilder LoadFromMemory(this IReverseProxyBuilder builder, IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
  10.         {
  11.             builder.Services.AddSingleton<IProxyConfigProvider>(new InMemoryConfigProvider(routes, clusters));
  12.             return builder;
  13.         }
  14.     }
  15. }
  16. namespace Yarp.ReverseProxy.Configuration
  17. {
  18.     public class InMemoryConfigProvider : IProxyConfigProvider
  19.     {
  20.         private volatile InMemoryConfig _config;
  21.         public InMemoryConfigProvider(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
  22.         {
  23.             _config = new InMemoryConfig(routes, clusters);
  24.         }
  25.         public IProxyConfig GetConfig() => _config;
  26.         public void Update(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
  27.         {
  28.             var oldConfig = _config;
  29.             _config = new InMemoryConfig(routes, clusters);
  30.             oldConfig.SignalChange();
  31.         }
  32.         private class InMemoryConfig : IProxyConfig
  33.         {
  34.             private readonly CancellationTokenSource _cts = new CancellationTokenSource();
  35.             public InMemoryConfig(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
  36.             {
  37.                 Routes = routes;
  38.                 Clusters = clusters;
  39.                 ChangeToken = new CancellationChangeToken(_cts.Token);
  40.             }
  41.             public IReadOnlyList<RouteConfig> Routes { get; }
  42.             public IReadOnlyList<ClusterConfig> Clusters { get; }
  43.             public IChangeToken ChangeToken { get; }
  44.             internal void SignalChange()
  45.             {
  46.                 _cts.Cancel();
  47.             }
  48.         }
  49.     }
  50. }
复制代码
  下面是它在 Startup.cs 中的调用方式:
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3.     var routes = new[]
  4.     {
  5.         new RouteConfig()
  6.         {
  7.             RouteId = "route1",
  8.             ClusterId = "cluster1",
  9.             Match = new RouteMatch
  10.             {
  11.                 Path = "{**catch-all}"
  12.             }
  13.         }
  14.     };
  15.     var clusters = new[]
  16.     {
  17.         new ClusterConfig()
  18.         {
  19.             ClusterId = "cluster1",
  20.             Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
  21.             {
  22.                 { "destination1", new DestinationConfig() { Address = "https://example.com" } }
  23.             }
  24.         }
  25.     };
  26.     services.AddReverseProxy()
  27.         .LoadFromMemory(routes, clusters);
  28. }
  29. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  30. {
  31.     if (env.IsDevelopment())
  32.     {
  33.         app.UseDeveloperExceptionPage();
  34.     }
  35.     app.UseRouting();
  36.     app.UseEndpoints(endpoints =>
  37.     {
  38.         endpoints.MapReverseProxy();
  39.     });
  40. }
复制代码
 
原文链接:https://www.cnblogs.com/ysmc/p/16727084.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表