是什么?
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
