目录

Welcome to YARP - 1.认识YARP并搭建反向代理服务

Welcome to YARP - 2.配置功能

Welcome to YARP - 3.负载均衡

Welcome to YARP - 4.限流

Welcome to YARP - 5.身份验证和授权

Welcome to YARP - 6.压缩、缓存

Welcome to YARP - 7.目标健康检查

Welcome to YARP - 8.分布式跟踪

哈哈哈,第一篇文章还说,只规划了8篇文章,写到配置功能的时候发现东西还是挺多的,还是拆分成小章节来说吧。目前成了10篇了—_—。写之前觉得配置功能应该没什么东西可讲,结果写着写着都想讲一嘴。然后就越写越多,大家看的时候可以选择性的跳过。

介绍

如果有同学不知道YARP是什么,YARP有哪些功能的同学请移步第一篇文章[Welcome to YARP - 1.认识YARP并搭建反向代理服务]( Welcome to YARP - 1.认识 YARP 之- 反向代理 - coding-y - 博客园 (cnblogs.com) )。接下来这篇文章主要讲解YARP的配置功能的第二小章节:配置提供程序

配置提供者(Configuration Providers)

我们之前两篇的示例中,都是通过配置文件去加载代理所需要的配置。当然,我们也可以选择以编程方式加载代理配置 。 我们可以通过提供几个实现 IProxyConfigProviderIProxyConfig 的类来做到这一点,上一篇文章中我们通过源码解读的方式,也提到过这两个接口,这里就不多说了。

结构

这个上篇文章也提到过,这里就简单带过一下吧:

IProxyConfigProvider 有一个 GetConfig() 返回 IProxyConfig 实例的方法。IProxyConfig 具有当前路由和集群的列表,以及一个用于信息过期,并通知YARP 重新加载配置的令牌IChangeToken ,这将导致 GetConfig() 会被再次调用。

内存中配置(In Memory Config)

通过 InMemoryConfigProvider 调用 LoadFromMemory 实现 IProxyConfigProvider 并启用直接在代码中指定路由和群集

services.AddReverseProxy().LoadFromMemory(routes, clusters);

若要稍后更新配置,请从服务容器解析 , InMemoryConfigProvider 并使用新的路由和集群列表进行调用 Update

httpContext.RequestServices.GetRequiredService<InMemoryConfigProvider>().Update(routes, clusters);

生命周期

启动

IProxyConfigProvider 应该在 DI 容器中注册为单一实例。在启动时,代理将解析此实例并调用 GetConfig() 。在第一次调用时,提供者可以选择:

  • 如果提供程序由于任何原因无法生成有效的代理配置,则引发异常。这将阻止应用程序启动。
  • 加载配置时同步阻止。这将阻止应用程序启动,直到有效的路由数据可用。
  • 或者,它可能选择在后台加载配置时返回空 IProxyConfig 实例。提供程序需要在配置可用时触发。 IChangeToken

原子性(Atomicity)

提供给代理的配置对象和集合应该是只读的,并且在通过GetConfig()将它们移交给代理后不会进行修改。

/// <summary>
/// 表示代理配置数据的快照。这些属性可能被多次访问,不应被修改。
/// </summary>
public interface IProxyConfig
{
private static readonly ConditionalWeakTable<IProxyConfig, string> _revisionIdsTable = new(); /// <summary>
/// A unique identifier for this revision of the configuration.
/// </summary>
string RevisionId => _revisionIdsTable.GetValue(this, static _ => Guid.NewGuid().ToString()); /// <summary>
/// Routes matching requests to clusters.
/// </summary>
IReadOnlyList<RouteConfig> Routes { get; } /// <summary>
/// Cluster information for where to proxy requests to.
/// </summary>
IReadOnlyList<ClusterConfig> Clusters { get; } /// <summary>
/// A notification that triggers when this snapshot expires.
/// </summary>
IChangeToken ChangeToken { get; }
}

可以看到GetConfig()加载过来的路由和集群列表都是只读的集合。

重新加载(Reload)

如果IChangeToken支持ActiveChangeCallbacks,那么一旦代理处理了初始配置,它就会使用此令牌注册回调。如果提供程序不支持回调,则HasChanged将每5分钟轮询一次。

当提供程序想要向代理提供新配置时,它应该:

  • 在后台加载该配置。
  • 路由和集群对象是不可变的,因此必须为任何新数据创建新实例。
  • 可以重用未更改路由和集群的对象,也可以创建新实例 - 将通过差异来检测更改。
  • (可选)使用 [IConfigValidator]( Interface IConfigValidator (microsoft.github.io) ) 验证配置,然后才 IChangeToken 从先前 IProxyConfig 实例发出新数据可用的信号。代理将再次调用 GetConfig() 以检索新数据。

重新加载配置与第一次加载配置时存在重要差异:

  • 新配置将与当前配置不同,并且只会更新修改的路由或集群。更新将以原子方式应用,并且仅影响新请求,而不会影响当前正在进行的请求。
  • 重新加载过程中的任何错误都将被记录和禁止。应用程序将继续使用上次已知的正确配置。
  • 如果 GetConfig() 抛出代,理将无法侦听将来的更改,因为 IChangeToken 是一次性的。

一旦验证并应用了新配置,代理将使用新的IChangeToken注册回调。请注意,如果有多个连续的重新加载信号,代理可能会跳过一些,并在准备好后立即加载下一个可用的配置。每个IProxyConfig都包含完整的配置状态,因此不会丢失任何内容。

上述描述的是刷新配置相关的内容,具体代码参考 ListenForConfigChanges(),可以结合代码一起看。

多配置源

参考前两篇文章的描述。

代码示例:

using Yarp.ReverseProxy.Configuration;
using Yarp.ReverseProxy.Model; var builder = WebApplication.CreateBuilder(args); builder.Services.AddReverseProxy()//添加ReverseProxy相关服务到DI
.LoadFromMemory(GetRoutes(), GetClusters());//从内存中加载配置 var app = builder.Build(); app.MapGet("/reload", (HttpContext httpContext) =>
{
httpContext.RequestServices.GetRequiredService<InMemoryConfigProvider>().Update(GetRoutes(), GetClusters("https://www.baidu.com"));
}); app.MapReverseProxy(); app.Run(); static RouteConfig[] GetRoutes()
{
return new[]
{
new RouteConfig()
{
RouteId = "route" + Random.Shared.Next(),
ClusterId = "cluster1",
Match = new RouteMatch
{
Path = "{**catch-all}"
}
}
};
}
static ClusterConfig[] GetClusters(string? address = null)
{
address ??= "https://cn.bing.com"; return new[]
{
new ClusterConfig()
{
ClusterId = "cluster1", Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
{
{ "destination1", new DestinationConfig() { Address = address } }
}
}
};
}

上述代码中我们通过内存去加载代理所需要的配置,而且使用了刷新配置功能,当我们访问这个站点时(http://localhost:5270)代理的是必应的站点,当我们去请求reload方法时(http://localhost:5270/reload)他会更改代理配置,从而代理百度的站点。完整代码已上传GitHub,在 YARP.ConfigurationProvider.Memory 文件夹下。

总结

这一章我们介绍并实践了配置提供者,通过内存来提供配置,通过代码来实现配置加载和更新。

当然我们还可以自定义配置提供者只要实现上述两个接口就可以。你可以实现基于 Redis 的和 数据库 的 配置提供者,感兴趣的小伙伴可以研究一下,这两种实现起来应该还是比较简单的(等有时间了,我会写个demo示例,先把规划的文章写完了再去搞这个)。

这篇文章就到这里,下一篇我们继续介绍配置过滤器(Configuration Filters)

Welcome to YARP - 2.2 配置功能 - 配置提供者(Configuration Providers)的更多相关文章

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

    介绍 基本 Yarp 示例显示从 appsettings.json 加载的代理配置.相反,代理配置可以从您选择的源以编程方式加载.您可以通过提供几个实现 IProxyConfigProvider 和 ...

  2. WCF学习之旅—WCF4.0中的简化配置功能(十五)

    六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...

  3. Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件

    Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件 下载地址 插件的操作很简单,下面是一些简单的实例. 1.安装 在谷歌应用商城搜索postman,如下图1-1所 ...

  4. qmake的配置功能(Configuration Features)

    Configuration Features qmake can be set up with extra configuration features that are specified in f ...

  5. Abp扩展之【配置功能】

    Abp的扩展功能非常强大,配合持久化可以很方便的配置系统.租户.用户的配置,关于ABP的配置请参考: http://www.cnblogs.com/farb/p/ABPSettingManagemen ...

  6. Apache运维中常用功能配置笔记梳理

    Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它.由于其开源.稳定.安全等特性而被广泛使用.下边记录了使用 Apache 以来经常用到的功能,做此梳理,作为日常运维 ...

  7. mysql主从备份功能配置与測试

    在高訪问量服务环境下,单机配置mysql服务将无法满足频繁快速的数据读写操作. 一旦mysql出现故障造成数据丢失.无法恢复. 因此.在mysql服务上启用主从备份功能,支持读写分离技术.最靠可的是搭 ...

  8. [转载]eclipse的远程调试功能配置

    原文地址:eclipse的远程调试功能配置作者:我的 用途:web应用部署并运行于外部(区别于eclipse环境中启动的)应用服务器中,当出现问题时,可以使用eclipse工程的源代码进行跟踪调试. ...

  9. OpenvSwitch系列之五 网桥特性功能配置

    Open vSwitch系列之一 Open vSwitch诞生 Open vSwitch系列之二 安装指定版本ovs Open vSwitch系列之三 ovs-vsctl命令使用 Open vSwit ...

  10. Nginx常用功能配置二

    Nginx常用功能配置二 Nginx location匹配设置 location作用:可以根据用户请求的URI来执行不同的应用,根据用户请求的网站的地址URL匹配. location语法: locat ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (193)-- 算法导论14.3 1题

    一.用go语言,写出作用于区间树的结点且在 〇(1) 时间内更新 max 属性的过程 LEFT-ROTATE 的伪代码. 文心一言: 以下是一个简单的LEFT-ROTATE的伪代码,它对一个二叉搜索树 ...

  2. 常用TS总结

    自己常用的 TS 写法总结,应该会一直更新.可使用 TS在线编译 校验 TS 语法. 基本用法 普通 const num: number = 10 const isStop: boolean = fa ...

  3. Linux通过fdisk或者parted进行磁盘分区,然后格式化和挂载磁盘

    磁盘分区是Linux的常用命令,其中fdisk和parted命令最为常用.但是当磁盘大于2T时,fdisk只能分到2T. 比如4T的磁盘,fdisk只能分2T的主分区出来,parted可以直接分成4T ...

  4. vue-element-admin iframes 组件 保留 iframe 操作状态

    由于没有时间去维护这个功能,这个仓库我暂停了,当前博客内容和代码只作为实现思路参考 代码贴前面,gitee地址:https://gitee.com/chkhk/vue-element-admin 可以 ...

  5. [MyArch]我的Archlinux与bspwm的重生之途

    0x00 前言碎语 2023.8.19 好久不见.这些日子一直在和bspwm和archlinux打交道.自从上次NepCTF的前几天和CuB3y0nd小师傅的bspwm配置打交道之后我一发不可收拾.中 ...

  6. NC20545 [HEOI2012]采花

    题目链接 题目 题目描述 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了 \(n\) 朵花,花有 \(c\) 种颜色(用整 ...

  7. Dota2参议院

    Dota2参议院 Dota2的世界里有两个阵营:Radiant天辉和Dire夜魇 Dota2参议院由来自两派的参议员组成.现在参议院希望对一个Dota2游戏里的改变作出决定.他们以一个基于轮转过程的投 ...

  8. Oracle设置和删除不可用列

    Oracle设置和删除不可用列 1.不可用列是什么? 就是表中的1个或多个列被ALTER TABLE-SET UNUSED 语句设置为无法再被程序利用的列. 2.使用场景? If you are co ...

  9. 解决webservice接口调用报错:java.lang.ClassFormatError: Absent Code ... javax/mail/internet/MimeMultip

    今天使用java axis调用.net发布的webservice接口报了个错,排查半天,感觉代码逻辑没问题,最后发现是jar包冲突!!! 调用接口相关代码: String url="http ...

  10. [攻防世界][Reverse]xxxorrr

    将目标文件拖入IDA 反汇编main函数 __int64 __fastcall main(int a1, char **a2, char **a3) { int i; // [rsp+Ch] [rbp ...