新余之窗网:.Net微服务实践(三):Ocelot设置路由和请求聚合

admin 7个月前 (04-08) 科技 44 0

目录
  • 设置
  • 路由
    • 基本设置
    • 占位符
    • 万能模板
    • 优先级
    • 查询参数
  • 请求聚合
    • 默认聚合
    • 自界说聚合
  • 最后

在上篇.Net微服务实践(二):Ocelot先容和快速最先中我们先容了Ocelot,创建了一个Ocelot Hello World程序,接下来,我们会先容Oclot的主要特征路由和另外一个特征请求聚合。这些特征都是通过设置来实现的。

设置

{
    "ReRoutes": [],
    "GlobalConfiguration": {}
}

Ocelot的设置文件包罗两个节点: ReRoutes和GlobalConfiguration

  • ReRoutes - 告诉Ocelot若何处置上游的请求
  • GlobalConfiguration - 全局设置,此节点的设置允许笼罩ReRoutes内里的设置,你可以在这里举行通用的一些设置信息

Ocelot的完整设置项如下

{
          "DownstreamPathTemplate": "/",
          "UpstreamPathTemplate": "/",
          "UpstreamHttpMethod": [
              "Get"
          ],
          "DownstreamHttpMethod": "",
          "DownstreamHttpVersion": "",
          "AddHeadersToRequest": {},
          "AddClaimsToRequest": {},
          "RouteClaimsRequirement": {},
          "AddQueriesToRequest": {},
          "RequestIdKey": "",
          "FileCacheOptions": {
              "TtlSeconds": 0,
              "Region": ""
          },
          "ReRouteIsCaseSensitive": false,
          "ServiceName": "",
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
              {
                  "Host": "localhost",
                  "Port": 51876,
              }
          ],
          "QoSOptions": {
              "ExceptionsAllowedBeforeBreaking": 0,
              "DurationOfBreak": 0,
              "TimeoutValue": 0
          },
          "LoadBalancer": "",
          "RateLimitOptions": {
              "ClientWhitelist": [],
              "EnableRateLimiting": false,
              "Period": "",
              "PeriodTimespan": 0,
              "Limit": 0
          },
          "AuthenticationOptions": {
              "AuthenticationProviderKey": "",
              "AllowedScopes": []
          },
          "HttpHandlerOptions": {
              "AllowAutoRedirect": true,
              "UseCookieContainer": true,
              "UseTracing": true,
              "MaxConnectionsPerServer": 100
          },
          "DangerousAcceptAnyServerCertificateValidator": false
      }

完整设置项中的每一项详细寄义和作用接下来会逐一先容,大的设置项的主要寄义如下:

  • Downstream - 下游服务设置
  • UpStream - 上游服务设置
  • Aggregates - 服务聚合设置
  • ServiceName, LoadBalancer, UseServiceDiscovery - 设置服务发现
  • AuthenticationOptions - 设置服务认证
  • RouteClaimsRequirement - 设置Claims鉴权
  • RateLimitOptions - 限流设置
  • FileCacheOptions - 缓存设置
  • QosOptions - 服务质量与熔断
  • DownstreamHeaderTransform - 头信息转发

路由

基本设置

在上一篇的hello world程序中使用的就是基本设置

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/orders",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5001
        }
      ],
      "UpstreamPathTemplate": "/api/orders",
      "UpstreamHttpMethod": [ "Get" ]
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5000"
  }
}
  • BaseUrl - Ocelot的服务运行地址,要特别注重一下BaseUrl是我们外部露出的Url,好比我们的Ocelot运行在http://localhost:5000,然则前面有一个 nginx绑定了域名http://api.demo.com,那这里我们的BaseUrl就是 http://api.demo.com
  • UpstreamPathTemplate、UpstreamHttpMethod - 设置上游服务器请求URL
  • DownstreamPathTemplate、DownstreamScheme、DownstreamHostAndPorts - 设置下游服务器请求URL

在基本设置的示例中:要实现的功效就是将 http://localhost:5000/api/orders GET 请求路由到 http://localhost:5001/api/orders GET

占位符

在Ocelot中,可以以{something}的形式将变量的占位符添加到模板中。占位符变量需要同时出现在DownstreamPathTemplate和UpstreamPathTemplate属性中。请求时Ocelot将实验请求时举行替换

{
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5002
        }
      ],
      "UpstreamPathTemplate": "/api/{everything}",
      "UpstreamHttpMethod": [ "Get" ]
}

示例说明:所有http://localhost:5000/api/XXXXXX的请求都市路由到http://localhost:5002/api/XXXXXX

例如http://localhost:5000/api/products 路由到 http://localhost:5002/api/products

例如http://localhost:5000/api/products/1 路由到 http://localhost:5002/api/products/1

验证

修改设置,运行示例程序, 接见http://localhost:5000/api/products,返回了产物数据

注重:在添加Ocelot.json文件时 .AddJsonFile("Ocelot.json",false,true), 第三个参数是指定文件发生变化时,是否重新加载,示例程序中是true. 以是我们只要修改运行目录下的设置文件,不用重新运行示例程序。

万能模板

既然占位符可以做通用匹配,自然而然就有一种设置可以匹配所有请求

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

示例说明: 转发所有的请求到http://localhost:5002

验证

修改设置,运行示例程序, 接见http://localhost:5000/api/products,返回了产物数据

优先级

若是一个上游请求有多个路由设置都能匹配,到底该使用哪个路由呢? 路由可以设置优先级(Priority), 0最小,路由会使用优先级高的(说明:若是多个匹配路由优先级一样,则按顺序使用第一个)

  • 在product-api中添加一个category api
[ApiController]
public class CategoryController : ControllerBase
{
    // GET: api/Product
    [Route("api/categories")]
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "电子产物", "医护用品" };
    }
}
  • 修改Ocelot.json设置文件如下
{
  "DownstreamPathTemplate": "/api/products",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 5002
    }
  ],
  "UpstreamPathTemplate": "/api/products",
  "UpstreamHttpMethod": [ "Get" ],
  "Priority": 0
},
{
  "DownstreamPathTemplate": "/api/categories",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 5002
    }
  ],
  "UpstreamPathTemplate": "/api/{everything}",
  "UpstreamHttpMethod": [ "Get" ],
  "Priority": 1
}

若是这时接见http://localhost:5000/api/products, 人人猜一下,是返回产物数据照样种别数据?

验证

修改设置,运行示例程序, 接见http://localhost:5000/api/products,返回了种别数据, 由于种别路由的优先级是1, 优先级更高

查询参数

  • 在order-api中添加一个订单明细的api\
[Route("api/orders/{id}")]
[HttpGet]
public string Get(int id)
{
    string order = string.Empty;
    switch(id)
    {
        case 1:
            order = "刘明的订单";
            break;
        case 2:
            order = "王天的订单";
            break;
        default:
            order = "没有找到订单";
            break;
    }
    return order;

}
  • 修改Ocelot.json设置如下
{
  "DownstreamPathTemplate": "/api/orders/{id}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 5001
    }
  ],
  "UpstreamPathTemplate": "/api/orders?id={id}",
  "UpstreamHttpMethod": [ "Get" ]
}

我们期望的效果是,当接见http://localhost:5000/api/orders?id=1 (下游服务现实没这个接口)时 路由到http://localhost:5001/api/orders/1返回订单明细

验证

修改设置,运行示例程序, 接见http://localhost:5000/api/orders?id=1,返回了订单明细数据

请求聚合

有一种场景,前端一个页面,挪用了多个API,要同时开多个毗邻几回挪用才气所有所需要的数据,为了削减不必要的请求和开销,Ocelot也支持请求聚合

默认聚合

  • 修改设置文件,在ReRoutes 添加如下设置
{
  "DownstreamPathTemplate": "/api/orders",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 5001
    }
  ],
  "UpstreamPathTemplate": "/api/orders",
  "UpstreamHttpMethod": [ "Get" ],
  "Key": "Orders"
},
{
  "DownstreamPathTemplate": "/api/products",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 5002
    }
  ],
  "UpstreamPathTemplate": "/api/products",
  "UpstreamHttpMethod": [ "Get" ],
  "Priority": 0,
  "Key": "Products"
}

人人注重一下,这和之前的设置有什么区别? 区别就是再每一个路由设置下多了一个 Key, Key的值可以随便界说(但建议照样按营业寄义界说)

  • 在Ocelot.json中添加如下设置
"Aggregates": [
    {
      "ReRouteKeys": [
        "Orders",
        "Products"
      ],
      "UpstreamPathTemplate": "/api/aggregates"
    }
  ]

注重Aggregates设置是和在ReRoutes设置平级的

{
    "ReRoutes": [],
    "Aggregates": [],
    "GlobalConfiguration": {}
}

示例说明: 当接见http://localhost:5000/api/aggregates, 会同时返回订单数据和产物数据

运行示例举行验证

既然是多个请求聚合,那么问题来了:

  • 若是其中一个服务宕机,会怎么样?

    我们住手订单服务,再次当接见http://localhost:5000/api/aggregates, 效果返回500
  • 若是其中一个服务不是宕机,而是返回500,会怎么样?

    我们修改order-api代码,在其中抛出异常
// GET: api/Product
[Route("api/orders")]
[HttpGet]
public  IEnumerable<string> Get()
{
    throw new Exception("获取所有订单失足");
}

再次运行示例,接见http://localhost:5000/api/aggregates,Response是200, 然则body中Products节点是正常的产物数据,Orders节点内里的数据是异常信息

自界说聚合

若是默认的聚合返回的效果数据结构不是我们想要的,想要修改怎么办?谜底是使用自界说聚合

  • 在ocelot-gateway中, 添加一个自动以聚合器FakeDefinedAggregator, 必须实现IDefinedAggregator接口。这个聚合器的功效很简单,就是将两个聚合请求的效果,用逗号拼接起来返回
public class FakeDefinedAggregator : IDefinedAggregator
{
    public FakeDefinedAggregator(FakeDepdendency dep)
    {
    }

    public async Task<DownstreamResponse> Aggregate(List<DownstreamContext> responses)
    {
        var one = await responses[0].DownstreamResponse.Content.ReadAsStringAsync();
        var two = await responses[1].DownstreamResponse.Content.ReadAsStringAsync();

        var merge = $"{one}, {two}";
        var headers = responses.SelectMany(x => x.DownstreamResponse.Headers).ToList();
        return new DownstreamResponse(new StringContent(merge), HttpStatusCode.OK, headers, "some reason");
    }
}
  • 注入自界说聚合器
services.AddOcelot()
        .AddSingletonDefinedAggregator<FakeDefinedAggregator>();
  • 在Ocelot.json中修改设置,指定自界说聚合器
"Aggregates": [
    {
      "ReRouteKeys": [
        "Orders",
        "Products"
      ],
      "UpstreamPathTemplate": "/api/aggregates",
      "Aggregator": "FakeDefinedAggregator"
    }
  ],

与之前的设置相比,多了如下的设置,就是指定自界说聚合器的

"Aggregator": "FakeDefinedAggregator"

验证

修改设置,运行示例程序, 接见http://localhost:5000/api/aggregate, 验证返回效果

最后

本篇我们先容了Ocelot设置,只要特征路由,以及请求聚合。接下里我们会先容Ocelot的其他特征:限流熔断、负载平衡

示例代码下载地址: https://github.com/lcyhjx/ocelot-demo/tree/master

,

Sunbet

Sunbet www.sunbet.xyz是Sunbet指定的Sunbet官网,Sunbet提供Sunbet(Sunbet)、Sunbet、申博代理合作等业务。

皇冠APP声明:该文看法仅代表作者自己,与本平台无关。转载请注明:新余之窗网:.Net微服务实践(三):Ocelot设置路由和请求聚合

网友评论

  • (*)

最新评论

标签列表

    文章归档

    站点信息

    • 文章总数:530
    • 页面总数:0
    • 分类总数:8
    • 标签总数:893
    • 评论总数:151
    • 浏览总数:9270