是什么?

Yarp.ReverseProxy 是微软开源的基于 .Net Core 的反向代理 SDK,使用它能够非常方便的构建一个自己的高性能网关。项目地址:https://microsoft.github.io/reverse-proxy/articles/getting-started.html

想更多了解,可查看基于 **Yarp.ReverseProxy** 的网关开源项目:https://github.com/hstarorg/bizgw

怎么用?

基础使用

使用也非常简单,直接在 .Net Core 的项目中几句代码即可使用:

  1. using GatewayDemo.CustomConfigration;
  2. using Yarp.ReverseProxy.Configuration;
  3. // 应用建造器
  4. var builder = WebApplication.CreateBuilder(args);
  5. // 添加反向代理能力,并从配置文件 appsettings.json 加载反向代理配置
  6. builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
  7. // 构建应用
  8. var app = builder.Build();
  9. app.MapReverseProxy();
  10. // 启动应用
  11. app.Run();

其对应的配置文件 appsettings.json内容如下:

  1. {
  2. "ReverseProxy": {
  3. "Routes": {
  4. "route1": {
  5. "ClusterId": "cluster1",
  6. "Match": {
  7. "Path": "{**catch-all}"
  8. }
  9. }
  10. },
  11. "Clusters": {
  12. "cluster1": {
  13. "LoadBalancingPolicy": "PowerOfTwoChoices", // Alternatively PowerOfTwoChoices - 选择两个随机的目标,然后从中选择一个更少请求的目标, "FirstAlphabetical" - 字母序, "Random" - 随机, "RoundRobin" - 轮询, "LeastRequests" - 所有目标中选择分配请求最少的目标
  14. "Destinations": {
  15. "cluster1/destination1": {
  16. "Address": "http://172.28.64.1:8000/"
  17. },
  18. "cluster1/destination2": {
  19. "Address": "https://dojo.hstar.vip/"
  20. }
  21. }
  22. }
  23. }
  24. }
  25. }

从数据库加载配置

控制配置刷新

理解

配置文件说明

全量配置文件说明: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

  1. {
  2. "ReverseProxy": {
  3. // 在 Routes 节点配置需要反向代理的路由表
  4. "Routes": {
  5. // 第一个路由配置(最简配置)
  6. "minimumroute" : { // 路由名称,可自定义
  7. // 该路由所关联的集群配置,也就是目标服务器配置
  8. "ClusterId": "minimumcluster",
  9. "Match": { // 匹配规则
  10. "Path": "{**catch-all}"
  11. }
  12. },
  13. // 第二个路由配置(全量)
  14. "allrouteprops" : {
  15. "ClusterId": "allclusterprops"
  16. "Order" : 100, // 路由顺序,数字越小优先级越高
  17. "Authorization Policy" : "Anonymous", // 认证策略,可选 "Default", "Anonymous"
  18. "CorsPolicy" : "Default", // Cors 策略,可选 "Default", "Disable"
  19. "Match": { //匹配 /something/*
  20. "Path": "/something/{**remainder}", // The path to match using ASP.NET syntax.
  21. "Hosts" : [ "www.aaaaa.com", "www.bbbbb.com"], // 限定 Host,不设置就是不限制
  22. "Methods" : [ "GET", "PUT" ], // Heep Methods 限定,不指定就是不限制
  23. "Headers": [ // 请求头限定,不指定就是不限制
  24. {
  25. "Name": "MyCustomHeader", // 请求头名称
  26. "Values": [ "value1", "value2", "another value" ], // 规则值
  27. "Mode": "ExactHeader", // 匹配模式,可选:"ExactHeader", "HeaderPrefix", "Exists" , "Contains", "NotContains"
  28. "IsCaseSensitive": true // 是否区分大小写
  29. }
  30. ],
  31. "QueryParameters": [ // 查询字符串限定,不设置就是不限制
  32. {
  33. "Name": "MyQueryParameter", // 参数名
  34. "Values": [ "value1", "value2", "another value" ], // 规则值
  35. "Mode": "Exact", // 匹配模式,可选 "Exact", "Prefix", "Exists" , "Contains", "NotContains"
  36. "IsCaseSensitive": true
  37. }
  38. ]
  39. },
  40. "MetaData" : { // 元数据(KV对象),可以在自定义扩展中使用
  41. "MyName" : "MyValue"
  42. },
  43. "Transforms" : [ // List of transforms. See ./Transforms.html for more details
  44. {
  45. "RequestHeader": "MyHeader",
  46. "Set": "MyValue",
  47. }
  48. ]
  49. }
  50. },
  51. // 转发服务器配置
  52. "Clusters": {
  53. "minimumcluster": {
  54. "Destinations": {
  55. "example.com": { // 目的地 1,名字自定义
  56. "Address": "http://www.example.com/" // 要转发的目标地址
  57. }
  58. }
  59. },
  60. "allclusterprops": { // 一个比较全面的目的地配置
  61. "Destinations": {
  62. "first_destination": {
  63. "Address": "https://contoso.com" // 目标地址
  64. },
  65. "another_destination": {
  66. "Address": "https://10.20.30.40",
  67. "Health" : "https://10.20.30.40:12345/test" // Health Check 地址,会覆盖 HealthCheck.Active 下的 Path
  68. }
  69. },
  70. "LoadBalancingPolicy" : "PowerOfTwoChoices", // 负载均衡策略: PowerOfTwoChoices - 选择两个随机的目标,然后从中选择一个更少请求的目标, "FirstAlphabetical" - 字母序, "Random" - 随机, "RoundRobin" - 轮询, "LeastRequests" - 所有目标中选择分配请求最少的目标
  71. "SessionAffinity": {
  72. "Enabled": true, // Defaults to 'false'
  73. "Policy": "Cookie", // Default, alternatively "CustomHeader"
  74. "FailurePolicy": "Redistribute", // default, Alternatively "Return503"
  75. "Settings" : {
  76. "CustomHeaderName": "MySessionHeaderName" // Defaults to 'X-Yarp-Proxy-Affinity`
  77. }
  78. },
  79. "HealthCheck": { // 健康检查配置
  80. "Active": { // Makes API calls to validate the health.
  81. "Enabled": "true",
  82. "Interval": "00:00:10", // 检查间隔
  83. "Timeout": "00:00:10", // 超时时间
  84. "Policy": "ConsecutiveFailures",
  85. "Path": "/api/health" // 健康检查地址
  86. },
  87. "Passive": { // Disables destinations based on HTTP response codes
  88. "Enabled": true, // Defaults to false
  89. "Policy" : "TransportFailureRateHealthPolicy", // Required
  90. "ReactivationPeriod" : "00:00:10" // 10s
  91. }
  92. },
  93. "HttpClient" : { // Configuration of HttpClient instance used to contact destinations
  94. "SSLProtocols" : "Tls13",
  95. "DangerousAcceptAnyServerCertificate" : false,
  96. "MaxConnectionsPerServer" : 1024,
  97. "EnableMultipleHttp2Connections" : true,
  98. "RequestHeaderEncoding" : "Latin1" // How to interpret non ASCII characters in header values
  99. },
  100. "HttpRequest" : { // Options for sending request to destination
  101. "ActivityTimeout" : "00:02:00",
  102. "Version" : "2",
  103. "VersionPolicy" : "RequestVersionOrLower",
  104. "AllowResponseBuffering" : "false"
  105. },
  106. "MetaData" : { // Custom Key value pairs
  107. "TransportFailureRateHealthPolicy.RateLimit": "0.5", // Used by Passive health policy
  108. "MyKey" : "MyValue"
  109. }
  110. }
  111. }
  112. }
  113. }

实体设计

默认的配置是非常灵活且强大的,在实际业务使用中,我们需要考虑数据的存储和用户的配置结构,以下为整体设计。

转发配置

如下假设均在分布式部署前提下:

  1. 每一个 App 都会部署 1 ~ N 个实例
  2. 每一个请求都可以配置 0~N 个转发地址(直接按地址转发)和 0~N 个转发应用(直接按应用转发),但两者至少有 1 个

请求转换(核心)

官方文档参见:https://microsoft.github.io/reverse-proxy/articles/transforms.html