是什么?
Yarp.ReverseProxy 是微软开源的基于 .Net Core
的反向代理 SDK,使用它能够非常方便的构建一个自己的高性能网关。项目地址:https://microsoft.github.io/reverse-proxy/articles/getting-started.html
想更多了解,可查看基于 **Yarp.ReverseProxy**
的网关开源项目:https://github.com/hstarorg/bizgw
怎么用?
基础使用
使用也非常简单,直接在 .Net Core
的项目中几句代码即可使用:
using GatewayDemo.CustomConfigration;
using Yarp.ReverseProxy.Configuration;
// 应用建造器
var builder = WebApplication.CreateBuilder(args);
// 添加反向代理能力,并从配置文件 appsettings.json 加载反向代理配置
builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
// 构建应用
var app = builder.Build();
app.MapReverseProxy();
// 启动应用
app.Run();
其对应的配置文件 appsettings.json
内容如下:
{
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "{**catch-all}"
}
}
},
"Clusters": {
"cluster1": {
"LoadBalancingPolicy": "PowerOfTwoChoices", // Alternatively PowerOfTwoChoices - 选择两个随机的目标,然后从中选择一个更少请求的目标, "FirstAlphabetical" - 字母序, "Random" - 随机, "RoundRobin" - 轮询, "LeastRequests" - 所有目标中选择分配请求最少的目标
"Destinations": {
"cluster1/destination1": {
"Address": "http://172.28.64.1:8000/"
},
"cluster1/destination2": {
"Address": "https://dojo.hstar.vip/"
}
}
}
}
}
}
从数据库加载配置
控制配置刷新
理解
配置文件说明
全量配置文件说明:https://microsoft.github.io/reverse-proxy/articles/config-files.html#all-config-properties 转换规则(Transforms)可参见:https://microsoft.github.io/reverse-proxy/articles/transforms.html#from-configuration 路由模板规则:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-template-reference
{
"ReverseProxy": {
// 在 Routes 节点配置需要反向代理的路由表
"Routes": {
// 第一个路由配置(最简配置)
"minimumroute" : { // 路由名称,可自定义
// 该路由所关联的集群配置,也就是目标服务器配置
"ClusterId": "minimumcluster",
"Match": { // 匹配规则
"Path": "{**catch-all}"
}
},
// 第二个路由配置(全量)
"allrouteprops" : {
"ClusterId": "allclusterprops"
"Order" : 100, // 路由顺序,数字越小优先级越高
"Authorization Policy" : "Anonymous", // 认证策略,可选 "Default", "Anonymous"
"CorsPolicy" : "Default", // Cors 策略,可选 "Default", "Disable"
"Match": { //匹配 /something/*
"Path": "/something/{**remainder}", // The path to match using ASP.NET syntax.
"Hosts" : [ "www.aaaaa.com", "www.bbbbb.com"], // 限定 Host,不设置就是不限制
"Methods" : [ "GET", "PUT" ], // Heep Methods 限定,不指定就是不限制
"Headers": [ // 请求头限定,不指定就是不限制
{
"Name": "MyCustomHeader", // 请求头名称
"Values": [ "value1", "value2", "another value" ], // 规则值
"Mode": "ExactHeader", // 匹配模式,可选:"ExactHeader", "HeaderPrefix", "Exists" , "Contains", "NotContains"
"IsCaseSensitive": true // 是否区分大小写
}
],
"QueryParameters": [ // 查询字符串限定,不设置就是不限制
{
"Name": "MyQueryParameter", // 参数名
"Values": [ "value1", "value2", "another value" ], // 规则值
"Mode": "Exact", // 匹配模式,可选 "Exact", "Prefix", "Exists" , "Contains", "NotContains"
"IsCaseSensitive": true
}
]
},
"MetaData" : { // 元数据(KV对象),可以在自定义扩展中使用
"MyName" : "MyValue"
},
"Transforms" : [ // List of transforms. See ./Transforms.html for more details
{
"RequestHeader": "MyHeader",
"Set": "MyValue",
}
]
}
},
// 转发服务器配置
"Clusters": {
"minimumcluster": {
"Destinations": {
"example.com": { // 目的地 1,名字自定义
"Address": "http://www.example.com/" // 要转发的目标地址
}
}
},
"allclusterprops": { // 一个比较全面的目的地配置
"Destinations": {
"first_destination": {
"Address": "https://contoso.com" // 目标地址
},
"another_destination": {
"Address": "https://10.20.30.40",
"Health" : "https://10.20.30.40:12345/test" // Health Check 地址,会覆盖 HealthCheck.Active 下的 Path
}
},
"LoadBalancingPolicy" : "PowerOfTwoChoices", // 负载均衡策略: PowerOfTwoChoices - 选择两个随机的目标,然后从中选择一个更少请求的目标, "FirstAlphabetical" - 字母序, "Random" - 随机, "RoundRobin" - 轮询, "LeastRequests" - 所有目标中选择分配请求最少的目标
"SessionAffinity": {
"Enabled": true, // Defaults to 'false'
"Policy": "Cookie", // Default, alternatively "CustomHeader"
"FailurePolicy": "Redistribute", // default, Alternatively "Return503"
"Settings" : {
"CustomHeaderName": "MySessionHeaderName" // Defaults to 'X-Yarp-Proxy-Affinity`
}
},
"HealthCheck": { // 健康检查配置
"Active": { // Makes API calls to validate the health.
"Enabled": "true",
"Interval": "00:00:10", // 检查间隔
"Timeout": "00:00:10", // 超时时间
"Policy": "ConsecutiveFailures",
"Path": "/api/health" // 健康检查地址
},
"Passive": { // Disables destinations based on HTTP response codes
"Enabled": true, // Defaults to false
"Policy" : "TransportFailureRateHealthPolicy", // Required
"ReactivationPeriod" : "00:00:10" // 10s
}
},
"HttpClient" : { // Configuration of HttpClient instance used to contact destinations
"SSLProtocols" : "Tls13",
"DangerousAcceptAnyServerCertificate" : false,
"MaxConnectionsPerServer" : 1024,
"EnableMultipleHttp2Connections" : true,
"RequestHeaderEncoding" : "Latin1" // How to interpret non ASCII characters in header values
},
"HttpRequest" : { // Options for sending request to destination
"ActivityTimeout" : "00:02:00",
"Version" : "2",
"VersionPolicy" : "RequestVersionOrLower",
"AllowResponseBuffering" : "false"
},
"MetaData" : { // Custom Key value pairs
"TransportFailureRateHealthPolicy.RateLimit": "0.5", // Used by Passive health policy
"MyKey" : "MyValue"
}
}
}
}
}
实体设计
默认的配置是非常灵活且强大的,在实际业务使用中,我们需要考虑数据的存储和用户的配置结构,以下为整体设计。
转发配置
如下假设均在分布式部署前提下:
- 每一个 App 都会部署 1 ~ N 个实例
- 每一个请求都可以配置 0~N 个转发地址(直接按地址转发)和 0~N 个转发应用(直接按应用转发),但两者至少有 1 个
请求转换(核心)
官方文档参见:https://microsoft.github.io/reverse-proxy/articles/transforms.html