首页 > 其他分享 >Yarp 让系统内调度更灵活

Yarp 让系统内调度更灵活

时间:2022-11-17 16:47:01浏览次数:65  
标签:灵活 app 调度 Yarp 路由 https test localhost

简介

Yarp 是微软团队开发的一个反向代理组件, 除了常规的 http 和 https 转换通讯,它最大的特点是可定制化,很容易根据特定场景开发出需要的定制代理通道。

详细介绍:https://devblogs.microsoft.com/dotnet/announcing-yarp-1-0-release

源码仓库:https://github.com/microsoft/reverse-proxy

文档地址 :https://microsoft.github.io/reverse-proxy/

 

基础使用

1、创建 ASP.NET Core  空项目

使用 Visual Studio :

  使用 .NET CLI 命令行创建:
dotnet new web -o MyProxy

2、 修改代码 Program.cs 文件

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.MapGet("/Ping", () => "Hello World!");
app.MapReverseProxy();
app.Run();

3、修改配置文件 appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeAll": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      }
    }
  }
}

这里的配置是将所有的请求都转发到百度。

在 Program.cs 里,还注册了一个 Get 路由 Ping 。

4、启动项目

能够看到在浏览器访问程序监听的端口号后,显示的是百度的页面。打开 F12 ,看到请求头也是本地的,并不是百度的域名。

测试手动注册的路由 Ping :

能够显示正常。

5、问题整理

(1) Yarp 是不是只能做这种简单的转发?

不是,往下有配置文件说明。

(2) JSON 配置文件里有什么要注意的地方吗?

有。在这个演示的配置文件中 ReverseProxy:Clusters:cluster1:Destinations:destination1:Address 对应的值是:https://www.baidu.com/ ,如果去掉 www ,在项目启动后会跳转到百度首页,不是代理转发。去掉末尾的 / 符合没有任何影响。

(3) Yarp 会影响到程序中注册的路由吗?

不会影响到程序内部注册的路由。在 Program.cs 中无论 app.MapReverseProxy(); 在上还是在下,在访问 Ping 的时候,都是返回 Hello World!

var app = builder.Build();
app.MapReverseProxy();
app.MapGet("/Ping", () => "Hello World!");
app.Run();

 

进阶探索

1、多地址代理

 修改配置文件 appsettings.json ,实现默认路由跳转百度,当访问 /movie 是访问 b站。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeBaidu": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      },
      "routeBiliBili": {
        "ClusterId": "clusterBiliBili",
        "Match": {
          "Path": "/movie/{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      },
      "clusterBiliBili": {
        "Destinations": {
          "bilibili": {
            "Address": "https://www.bilibili.com/"
          }
        }
      }
    }
  }
}

 测试结果:

在后面输入路由 /movie 后能够跳转到b站。但是b站网页没有完整显示,图片都没有,这是网站上的策略问题,对于数据接口没有这些问题。

详细的配置文件说明,可以查看 https://microsoft.github.io/reverse-proxy/articles/config-files.html

2、规则匹配

网页上太多资源,为了方便测试,启用两个 api 接口。地址分别是:http://localhost:5241/ 和 https://localhost:7184/

两个 api 接口中分别注册 /test 路由。

// http://localhost:5241/
app.MapGet("/test", () => "Welcome to Api111!");

// https://localhost:7184/
app.MapGet("/test", () => "Welcome to Api222!");

启动两个 api 程序。

C:\Users\Test>curl http://localhost:5241/test
Welcome to Api111!

C:\Users\Test>curl https://localhost:7184/test
Welcome to Api222!

修改 MyProxy 项目的配置文件 appsettings.json 

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "routeOne": {
        "ClusterId": "clusterOne",
        "Match": {
          "Path": "/test/{**catch-all}",
          "QueryParameters": [
            {
              "Name": "number",
              "Values": [ "1" ]
            }
          ]
        }
      },
      "routeTwo": {
        "ClusterId": "clusterTwo",
        "Match": {
          "Path": "/test/{**catch-all}",
          "QueryParameters": [
            {
              "Name": "number",
              "Values": [ "2" ]
            }
          ]
        }
      },
      "routeBaidu": {
        "ClusterId": "clusterBaidu",
        "Match": {
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "clusterOne": {
        "Destinations": {
          "apiOne": {
            "Address": "http://localhost:5241/"
          }
        }
      },
      "clusterTwo": {
        "Destinations": {
          "apiTwo": {
            "Address": "https://localhost:7184/"
          }
        }
      },
      "clusterBaidu": {
        "Destinations": {
          "baidu": {
            "Address": "https://www.baidu.com/"
          }
        }
      }
    }
  }
}

Path :监听路由地址。

QueryParameters:匹配参数。

QueryParameters:Name:参数名。

QueryParameters:Values:参数值。

MyProxy 的监听端口是 http://localhost:5024/ 访问结果如下

C:\Users\Test>curl http://localhost:5024/ping
Hello World!

C:\Users\Test>curl http://localhost:5024/test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /test was not found on this server.</p>
</body></html>

C:\Users\Test>curl http://localhost:5024/test?number=1
Welcome to Api111!

C:\Users\Test>curl http://localhost:5024/test?number=2
Welcome to Api222!

能够根据参数以及参数值导向对应的地址。

3、问题整理

(1)为什么访问 /movie 不能正常显示网页。

因为 b站某些接口开启了防盗链,还有跨域检测。

(2)在根据参数匹配中,如果匹配的路由一样,监听的参数一样,参数值也一样会怎么样?

访问该路由地址会报错。

(3)路由匹配的优先级?

程序内注册的路由优先级最高,其次才是 Yarp 在配置文件里加载的。

 

小试牛刀

最近的工作是做企业内数据安全方面的。推动公司数据安全体系,通过技术手段提升公司信息安全。

有一个很老的OA系统,十几年了, .NET Framework 2.0 写的。漏洞一大堆,包括不限于xss、sql注入等,权限只到表单级别。浏览器上按下 F12 能查看到表单链接,直接复制出去,别人也能访问。

在这个系统上要做安全,我想的是在中间加代理,正好适合使用 Yarp 来完成,也方便写业务处理代码。嗯,很真实, .NET Core 写的,方便写业务代码。

用户登录成功后,会记录下用户的 Host 和 Cookie,每次访问的时候系统的时候,在 Yarp 这里都校验一下是否与用户登录时的匹配。

 

解决了两个问题:

1、从网络层捕获到所有的请求,方便后面做排查。参数、传值,出了事故可以找到责任人。

2、隔离真实的站点地址,杜绝弱安全等级网站暴露后被坏人攻击的风险。

 

踩坑集锦

1、non-ASCII 

项目要代理某网页,在使用下载功能的时候,接口返回 502 。

info: Yarp.ReverseProxy.Forwarder.HttpForwarder[48]
      ResponseHeaders: The destination returned a response that cannot be proxied back to the client.
      System.InvalidOperationException: Invalid non-ASCII or control character in header: 0x00E4
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ThrowInvalidHeaderCharacter(Char ch)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.ValidateHeaderValueCharacters(StringValues headerValues)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseHeaders.SetValueFast(String key, StringValues value)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpHeaders.Microsoft.AspNetCore.Http.IHeaderDictionary.set_Item(String key, StringValues value)
         at Yarp.ReverseProxy.Forwarder.HttpTransformer.CopyResponseHeaders(HttpHeaders source, IHeaderDictionary destination)
         at Yarp.ReverseProxy.Forwarder.HttpTransformer.TransformResponseAsync(HttpContext httpContext, HttpResponseMessage proxyResponse)
         at Yarp.ReverseProxy.Transforms.Builder.StructuredTransformer.TransformResponseAsync(HttpContext httpContext, HttpResponseMessage proxyResponse)
         at Yarp.ReverseProxy.Forwarder.HttpForwarder.SendAsync(HttpContext context, String destinationPrefix, HttpMessageInvoker httpClient, ForwarderRequestConfig requestConfig, HttpTransformer transformer)

去 GitHub 翻 Issues

下载接口能正常访问,文件流也能完整地拿到。重写了所有的响应头没有用。这种不开源的商业站点,也猜不到字符编码。

最后妥协了,用了一个 .NET 服务在服务器上下载后再转发。

代理非常规服务接口时,一定要多测试。

 

标签:灵活,app,调度,Yarp,路由,https,test,localhost
From: https://www.cnblogs.com/webenh/p/16899927.html

相关文章

  • 数据集成平台关于【源平台调度&任务生命周期】
    任务调度者调度事件生产任务调度任务池-异步
AsynDispatcher--source实例化适配器执行消费任务实例化集成应用DataHubInstance
handleSourceDispatch()依赖注入集成方......
  • 数据集成平台关于【源平台调度&任务生命周期】
    任务调度者调度事件生产任务调度任务池-异步
AsynDispatcher--source实例化适配器执行消费任务实例化集成应用DataHubInstance
handleSourceDispatch()依......
  • 结对编程 电梯调度
    《软件工程基础》上机实验报告撰写要求 一、 纸张与页面要求1. 采用国际标准A4型打印纸或复印纸,纵向打印。2. 封页和页面按照下面模板书写(正文为:小四宋体1.5倍行......
  • Pod详解之Pod调度(亲和性调度)
    亲和性调度两种定向调度的方式,使用起来非常方便,但是也有一定的问题,那就是如果没有满足条件的Node,那么Pod将不会被运行,即使在集群中还有可用Node列表也不行,这就限制了它的......
  • Pod详解之Pod调度
    Pod调度在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。但是在实际使用中,这并不满足的需求,因为很多情况......
  • 基于多目标粒子群的微电网优化调度(附matlab代码)
    1、部分结果展示       %储能最大放电功率StorageMaxDischargingPower=250;%储能最大充电功率StorageMaxChargingPower=-200;%柴油发电机最大功率DGMa......
  • 直播CDN调度技术关键挑战与架构设计
    作者:胡济麟1、背景介绍1.1直播业务特点互联网视频直播是一种消息媒介形态,提供时产时消的内容,经过多年,已经发展出秀场、游戏、电商、体育等多种业务形态。主要特点是:内容实......
  • 《线程调度》
    (38条消息)Linux线程调度与优先级_modi000的博客-CSDN博客_linux线程优先级(38条消息)linux线程调度策略简述_独步逍遥&万界仙踪的博客-CSDN博客_linux线程调度......
  • 资源调度和服务编排技术架构
     从传统云网融合的角度出发,结合边缘计算、网络云化及智能控制的优势,在算力网络连接下实现更加广泛的算力资源纳管和动态调度。算力网络正是为了提高云、边、端三级计算的......
  • 真趣科技:多业务形态的企业需要灵活可配置的CRM系统
    苏州真趣信息科技有限公司,物联网领域国家高新技术企业。位置物联网领域博士后、博士领衔科研团队,荣获300余项专利、重磅荣誉、国际国内权威机构认证。公司旗下拥有“真趣......