一、安装Ocelot

在程序包管理器控制台输入以下命令安装Ocelot

Install-Package Ocelot

二、新建两个项目

我们新建两个.Net Core WebAPI项目如下:

 

直接就是最初始化的项目,只是我们在ExternalGateway项目中安装Ocelot,并且添加一个ocelot.json文件(也可以添加多个配置文件然后合并),文件内容如下:

{
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
},
"Routes": [
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}
]
}

然后注入Ocelot的服务和配置请求管道

builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
builder.Services.AddOcelot();
//......
app.UseOcelot().Wait();

然后我们运行两个项目就能通过ExternalGateway项目地址访问uthServer的地址

三、Routing的参数配置说明

1、路由

    {
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}

其中DownstreamPathTemplateDownstreamSchemeDownstreamHostAndPorts定义了请求将被转发到的URL。

参数DownstreamHostAndPorts是一个集合定义了请求转到任何下游服务的主机和端口,一般是单个即可,但是如果存在负载均衡到下游服务那就需要填写多个,并进行相关的负载均衡的配置。

参数UpstreamPathTemplate是标识用于给定下游请求的DownstreamPathTemplate对应的URL

参数UpstreamHttpMethod便于区分不同的HTTP的请求到相同的URL,可以设置为空允许全部的请求。

Ocelot中可以以{something}的形式为模板中的变量添加占位符,但是该占位符变量必须同时出现在DownstreamPathTemplateUpstreamPathTemplate的上下游配置中,Ocelot会尝试进行占位符值的替换。

默认请求路径的配置是不区分大小写的,如果需要修改通过以下参数配置:

"RouteIsCaseSensitive": true

2、全部捕获

Ocelot中还支持捕获全部路径的路由,用户可以指定他们想要匹配的所有流量。

像是如下的配置,所有的请求都将被代理。但是占位符{url}的名称不重要,可以使用任何名称。

{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 80,
}
],
"UpstreamPathTemplate": "/{url}",
"UpstreamHttpMethod": [ "Get" ]
}

但是全部捕获的优先级是最低的,如果存在其他配置,将会优先于此匹配。

3、优先级

可以通过Priorty参数来这是匹配上游请求路径的优先级,如下配置的情况下请求地址为/goods/delete的时候优先匹配/goods/{catchAll},因为0是最低的优先级,Priorty越大优先级越高。

{
"UpstreamPathTemplate": "/goods/{catchAll}"
"Priority": 0
}
{
"UpstreamPathTemplate": "/goods/delete"
"Priority": 1
}

4、上游主机

参数UpstreamHost允许我们设置该路由的上游主机,配置后仅当请求头的主机为我们的配置值,才会匹配该路由配置。如果没有配置UpstreamHost那就是任何主机头都可以。

{
"DownstreamPathTemplate": "/",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "10.0.10.1",
"Port": 80,
}
],
"UpstreamPathTemplate": "/",
"UpstreamHttpMethod": [ "Get" ],
"UpstreamHost": "somedomain.com"
}

如上述代码仅当主机头为somedomain.com的请求,才会匹配上述路由。如果存在两个相同的路由配置,但是一个设置了UpstreamHost一个没有设置,这样会匹配设置了的路由。

5、查询字符串

Ocelot中允许将查询字符串作为DownstreamPathTemplate的一部分,如下所示上游路径模板中的{unitId}将作为下游路径模板中的查询字符串参数unitId的值。

{
"Routes": [
{
"DownstreamPathTemplate": "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}",
"UpstreamPathTemplate": "/api/units/{subscriptionId}/{unitId}/updates",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50110
}
]
}
],
"GlobalConfiguration": {
}
}

此外Ocelot还允许将查询字符串放置在UpstreamPathTemplate中,以便将某些查询匹配到对应的服务,如下所示只能匹配查询参数为unitId的请求。

{
"Routes": [
{
"DownstreamPathTemplate": "/api/units/{subscriptionId}/{unitId}/updates",
"UpstreamPathTemplate": "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 50110
}
]
}
],
"GlobalConfiguration": {
}
}

四、聚合路由

Ocelot中允许使用聚合路由,聚合路由就是将多个路由的结果结合成一个进行返回。

首先我们将ocelot.json改为下面的配置,可以看到两个路由下各自有自己的Key,然后多了一个聚合路由Aggregates里面设置了对应的两个Key,并且该聚合路由的路径也被设置为了/getweatherforecastaggregate/{everything}

{
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
},
"Routes": [
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"Key": "WeatherForecast1"
},
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api2/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"Key": "WeatherForecast2"
}
],
"Aggregates": [
{
"RouteKeys": [
"WeatherForecast1",
"WeatherForecast2"
],
"UpstreamPathTemplate": "/getweatherforecastaggregate/{everything}"
}
]
}

然后我们请求对应的地址就可以看到返回了以两个Key为键的对应路由地址接口返回的信息,如果接口报错则返回空。这里需要注意,聚合路由Aggregates中的上游路径UpstreamPathTemplate其实对应的就是Route中的UpstreamPathTemplate,也就是说路由中的上游路径就是聚合路由的下游路径,对应的变量占位符啥的都会传递。

如果我们不满意返回的结果可以自定义聚合路由的来处理返回的结果,我们现在将oeclot.json中的聚合路由修改如下增加Aggregator参数

  "Aggregates": [
{
"RouteKeys": [
"WeatherForecast1",
"WeatherForecast2"
],
"UpstreamPathTemplate": "/getweatherforecastaggregate/{everything}",
"Aggregator": "MyAggregator"
}
]

然后我们创建一个与Aggregator参数同名的重写类,并且继承IDefinedAggregator接口重写Aggregate(List<HttpContext> responses)方法如下:

    public class MyAggregator: IDefinedAggregator
{
public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
{
var one = await ((DownstreamResponse)responses[0].Response.HttpContext.Items["DownstreamResponse"]).Content.ReadAsStringAsync();
//Response.Body不能获取,只能通过HttpContext.Items
//using var resReader1 = new StreamReader(responses[0].Response.Body);
//var one = await resReader1.ReadToEndAsync();
var two = await ((DownstreamResponse)responses[1].Response.HttpContext.Items["DownstreamResponse"]).Content.ReadAsStringAsync();
var my = $"\"{Guid.NewGuid()}\":{{comment:\"我是自定义聚合器返回内容\"}}";
var merge = $"{one}, {two},{my}";
List<Header> headers = new List<Header>();
return await Task.FromResult(new DownstreamResponse(new StringContent(merge), HttpStatusCode.OK, headers, "some reason"));
}
}

然后在注册该类,可以是瞬态注册等此处单例

builder.Services.AddOcelot().AddSingletonDefinedAggregator<MyAggregator>();

然后我们访问地址就可看到返回了我们添加的内容

Ocelot使用与设置路由Routing的更多相关文章

  1. RabbitMQ学习总结 第五篇:路由Routing

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  2. asp.net MVC 5 路由 Routing

    ASP.NET MVC ,一个适用于WEB应用程序的经典模型 model-view-controller 模式.相对于web forms一个单一的整块,asp.net mvc是由连接在一起的各种代码层 ...

  3. ASP.NET Core MVC 之路由(Routing)

     ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序的URL命名形式,使得它 ...

  4. 路由(Routing)

    路由(Routing)  ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序 ...

  5. RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重的错误日 ...

  6. ASP.NET Web API实践系列04,通过Route等特性设置路由

    ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程.在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一 ...

  7. linux dhcp 设置路由及主机名

    自动获取ipDHCP方式获取ip:dhclient [网络接口]释放通过DHCP获取的ip地址:dhclient -r [网络接口]查看网络接口 ifconfig -a(列出所有接口含禁用的) eth ...

  8. Vue-详解设置路由导航的两种方法: <router-link :to="..."> 和router.push(...)

    一.<router-link :to="..."> to里的值可以是一个字符串路径,或者一个描述地址的对象.例如: // 字符串 <router-link to= ...

  9. 【转】Vue-详解设置路由导航的两种方法: <router-link :to="..."> 和router.push(...)

    一.<router-link :to="..."> to里的值可以是一个字符串路径,或者一个描述地址的对象.例如: // 字符串 <router-link to= ...

  10. 配置子目录Web.config使其消除继承,iis7.0设置路由

    iis7.0设置路由 ,url转向,伪静态 <system.webServer>      <modules runAllManagedModulesForAllRequests=& ...

随机推荐

  1. Pod资源的基础管理操作(Kubernetes)

    Pod是Kubernetes API中的核心资源类型,它可以定义在JSON或者YAML格式的资源清单中,由资源管理命令进行陈述式声明管理.创建时通过create或apply命令将请求提交到API Se ...

  2. IDEA导出带源码的war包

    做作业时实验要求导出带源码的war包,网上找了一圈没找着,遂自行探索,摸出了些门道,在此分享. File->Project Structure->Project Setting->A ...

  3. JavaScript基础知识整理(变量)

    变量 ECMAScript变量有两种不同数据类型的值,分别是基本类型和引用类型,两者的不同在于基本类型值是简单的数据段,引用类型值一般指由多个值构成的对象 基本类型 基本数据类型包括5种:Undefi ...

  4. 突然连不上虚拟机,本地网络里没有VMnet8

    今天打开虚拟机,突然发现无法ping通网络了,但是能ping通虚拟机ip,打开我的window的网络适配器发现居然没有vmnet 8虚拟网卡了,防火墙什么的都设置好了,仍然不行,后来发现,在网络和共享 ...

  5. nmap扫描

    Nmap扫描 学习老师发的链接中的指令:https://www.cnblogs.com/nmap/p/6232207.html 下载了nmap软件 根据教学中的操作查找虚拟机的IP地址 并用主机对其扫 ...

  6. Git、GitHub、GitLab三者之间的区别

    1.Git Git是一个版本控制系统. 版本控制是一种用于记录一个或多个文件内容变化,方便我们查阅特定版本修订情况的系统. 总结: (1)分布式版本控制系统下的本地仓库包含代码库还有历史库,在本地就可 ...

  7. 在 Rime 上对输入法进行定制

    Rime Rime是什么?忘了!但是在用.而且很好用. 了解Rime历史,还是去官网吧! 定制 Rime有两个目录: 1. 程序目录 2. 用户目录 Rime 的程序目录 Windows 上 要看你安 ...

  8. 延期!欧盟新标EN IEC 62368-1:2020延至2024年7月6日生效

    近日,TC108X成员投票同意将EN IEC 62368-1:2020(对应IEC 62368-1第三版)的DOW (Date Of Withdrawn)日期由原先的2023年1月6日延长至2024年 ...

  9. 【UE4】GameplayTag的妙用(ActorTag)

    我不会抛下这个残破的世界 在现代游戏引擎中,有一个"Tag"的概念,无论是在Unreal还是Unity中,他们都有大同小异的tag实现. 此篇随笔以Actor Tag举例,简单讲解 ...

  10. 内部类(Java)

    内部类 基本介绍 概念:在一个类的内部再定义一个完整类 特点:编译之后可生成独立的字节码文件:内部类可以直接访问外部类的私有属性,不破坏封装性 分类:成员内部类:静态内部类:局部内部类:匿名内部类 p ...