Welcome to YARP - 2.3 配置功能 - 配置过滤器(Configuration Filters)
目录
Welcome to YARP - 1.认识YARP并搭建反向代理服务
- 2.1 - 配置文件(Configuration Files)
- 2.2 - 配置提供者(Configuration Providers)
- 2.3 - 配置过滤器(Configuration Filters)
哈哈哈,第一篇文章还说,只规划了8篇文章,写到配置功能的时候发现东西还是挺多的,还是拆分成小章节来说吧。目前成了10篇了—_—。写之前觉得配置功能应该没什么东西可讲,结果写着写着都想讲一嘴。然后就越写越多,大家看的时候可以选择性的跳过。
介绍
如果有同学不知道YARP
是什么,YARP
有哪些功能,或者对配置没有基本概念的同学请看前几篇文章,接下来这篇文章主要讲解YARP
的配置功能的第三小章节:配置过滤器
配置过滤器(Configuration Filters)
YARP
的 routes
, clusters
和 destinations
的配置可以通过配置文件或其他配置提供者加载过来。
而配置过滤器可用于在验证和应用原始输入(原始配置)之前对其进行修改。
加载配置 => 配置过滤器 => 验证配置 => 应用配置
过滤器可用于多种目的,例如:
- 使用来自其他源(如部署环境)的数据补充配置字段
- 应用系统默认值
- 应用通用设置并强制实施策略
- 替换占位符值 (下面的演示就是此场景)
- 规范化和纠错
AddConfigFilter
配置过滤器使用 AddConfigFilter
API 在依赖项注入系统中注册。可以添加任意数量的唯一过滤器,并将按添加顺序应用
using YARP.Configuration.ConfigFilter;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))//加载配置
.AddConfigFilter<CustomConfigFilter>();//注册配置过滤器
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapReverseProxy();
app.Run();
首先我们创建一个CustomConfigFilter类并继承 IProxyConfigFilter
接口,然后我们去实现ConfigureClusterAsync
方法和ConfigureRouteAsync
方法。在这两个方法中对路由信息和集群信息进行拦截和自定义处理。
每次加载或重新加载配置时,都会为每个路由和集群调用过滤器。可以选择返回未修改的原始输入或修改后的副本。
此示例把地址替换为环境变量中的目标地址,并将路由的 Order
字段设置为 1
using System.Text.RegularExpressions;
using Yarp.ReverseProxy.Configuration;
namespace YARP.Configuration.ConfigFilter;
public class CustomConfigFilter : IProxyConfigFilter
{
// 用于匹配文本中的双花括号{{}}包围的单词(字母数字字符)
private readonly Regex _exp = new("\\{\\{(\\w+)\\}\\}");
// 集群的配置过滤器,将依次传递给每个集群,它应该按原样返回,或者 克隆并创建具有更新更改的新版本
// 此示例查看目标地址(destination addresses),任何形式{{key}}都将被匹配到,并用此key获取环境变量里对应的value
// 作为环境变量。当托管在Azure等中时,这很有用,因为它能够以简单的方式替换
public ValueTask<ClusterConfig> ConfigureClusterAsync(ClusterConfig origCluster, CancellationToken cancel)
{
// 每个集群都有一个 destination 字典,它是只读的,所以我们将用更新创建一个 destination 字典
var newDests = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase);
foreach (var d in origCluster.Destinations)
{
var origAddress = d.Value.Address;
if (_exp.IsMatch(origAddress))
{
// 用先前定义的正则表达式_exp来匹配字符串,然后提取第一个匹配的结果的捕获组(Group)中索引为1的值: baidu。
var lookup = _exp.Matches(origAddress)[0].Groups[1].Value;
// 根据key(baidu):获取 value (https://www.baidu.com)
var newAddress = Environment.GetEnvironmentVariable(lookup);
if (string.IsNullOrWhiteSpace(newAddress))
{
throw new ArgumentException($"Configuration Filter Error: Substitution for '{lookup}' in cluster '{d.Key}' not found as an environment variable.");
}
// c# 9 "with" 语法: 克隆并初始化 record
var modifiedDest = d.Value with { Address = newAddress };
newDests.Add(d.Key, modifiedDest);
}
else
{
newDests.Add(d.Key, d.Value);
}
}
return new ValueTask<ClusterConfig>(origCluster with { Destinations = newDests });
}
public ValueTask<RouteConfig> ConfigureRouteAsync(RouteConfig route, ClusterConfig? cluster, CancellationToken cancel)
{
// Example: 不要让基于配置的路由优先于基于代码的路由。
// 数字越低,优先级越高。代码路由默认为0。
if (route.Order.HasValue && route.Order.Value < 1)
{
return new ValueTask<RouteConfig>(route with { Order = 1 });
}
return new ValueTask<RouteConfig>(route);
}
}
配置如下:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "{**catch-all}"
}
}
},
"Clusters": {
"cluster1": {
"Destinations": {
"cluster1/destination1": {
// 以下值将由regex找到,并作为环境变量查找
"Address": "{{baidu}}"
}
}
}
}
}
}
launchSettings.json
文件中环境变量设置如下:
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"baidu": "https://www.baidu.com"
}
总结
配置过滤器就结束了,我们通过实现IProxyConfigFilter
接口对配置进行替换,配置文件中写的是占位符{{baidu}},用它当作key,环境变量里才是我们的真实地址,通过配置过滤器去拦截并处理替换成真实的地址。这对于敏感数据及其有用。代码示例已上传GitHub:YARP.Configuration.ConfigFilter
这篇文章就到这里,下一篇我们介绍 YARP
的负载均衡功能。