zoukankan      html  css  js  c++  java
  • .NET Core 微服务—API网关(Ocelot) 教程 [四]

    前言:

      上一篇 介绍了Ocelot网关和认证服务的结合使用,本篇继续介绍Ocelot相关请求聚合和Ocelot限流

    一、请求聚合

      Ocelot允许声明聚合路由,这样可以把多个正常的Routes打包并映射到一个对象来对客户端的请求进行响应。

      例如:在获取订单记录时,也需要查看订单中对应的商品信息,这里的数据就来源于两个微服务:订单服务、商品服务。如果不使用聚合路由时,对于现实一个订单信息时,客户端需要调用两次服务请求,实际上会造成服务端额外的性能消耗。这是如果配置了聚合路由时,客户端只需要请求一次聚合路由,然后聚合路由会合并订单服务和商品服务的请求结果到一个对象中,并返回给客户端。使用Ocelot的此特性可以让你很容易的实现前后端分离的架构。接下来我们就来验证该功能的实现。

      在ocelot.json中进行如下配置:

       1、为每个Route设置一个Key属性:如:"Key": "Catalog"

       2、在ocelot.json中添加Aggregates节点,并指定RouteKeys中指定1中设置的Key值组成的数组,并设置UpstreamPathTemplate匹配上游用户请求;它的工作方式和正常的Route类似。

       调整后如下:

    {
      "Aggregates": [
        {
          "RouteKeys": [
            "Catalog",
            "Ordering"
          ],
          "UpstreamPathTemplate": "/GetOrderDetail/{id}"
        }
      ],
      "GlobalConfiguration": {
    
      },
      "Routes": [
        {
          "DownstreamPathTemplate": "/api/Values/{id}",
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",
              "Port": 5332
            }
          ],
          "UpstreamPathTemplate": "/Catalog/{id}",
          "UpstreamHttpMethod": [ "Get", "Post" ],
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "Key": "Catalog"
        },
        {
          "DownstreamPathTemplate": "/api/Values/{id}",
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",
              "Port": 5331
            }
          ],
          "UpstreamPathTemplate": "/Ordering/{id}",
          "UpstreamHttpMethod": [ "Get", "Post" ],
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "Key": "Ordering"
        }
      ]
    }

       3、如图调整项目代码:返回不同结果

        

       4、访问设置的聚合地址结果如下:

        返回结果为设置的Key组合的数据结构。

        

       5、如果服务出现异常会怎么样:

       a) 如果当某个服务出现异常会返回什么呢?接下来做个验证,修改订单服务返回结果:

     public IActionResult Get(int id)
     {
          throw new Exception("模拟异常");
     }

        

         如图所示返回的结果和正常是结构是相同的,只是Ordering返回的是异常信息;

       b) 如果某个服务宕机,回得到什么结果呢?接下来停止了Ordering服务访问结果如下,得到502错误

        

      6、如果默认的聚合返回的结果数据结构不是我们想要的,想要修改怎么办?答案是使用自定义聚合

       a)添加一个自动以聚合器FakeDefinedAggregator, 必须实现IDefinedAggregator接口。这个聚合器的功能很简单,就是将两个聚合请求的结果,用逗号拼接起来返回

        public class FakeDefinedAggregator : IDefinedAggregator
        {
            public FakeDefinedAggregator()
            {
            }
            public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
            {
    
                List<string> result = new List<string>();
                foreach (var item in responses)
                {
                    byte[] tmp = new byte[item.Response.Body.Length];
                    await item.Response.Body.ReadAsync(tmp, 0, tmp.Length);
                    var val = Encoding.UTF8.GetString(tmp);
                    result.Add(val);
                }
                var merge = string.Join(";", result.ToArray());
                List<Header> headers = new List<Header>();
                return new DownstreamResponse(new StringContent(merge), HttpStatusCode.OK, headers, "some reason");
            }
        }

       b)注册自定义聚合器

    services.AddOcelot()
            .AddSingletonDefinedAggregator<FakeDefinedAggregator>();

       c)修改ocelot.json配置文件

    "Aggregates": [
        {
          "ReRouteKeys": [
            "Orders",
            "Products"
          ],
          "UpstreamPathTemplate": "/GetOrderDetail/{id}",
    "Aggregator": "FakeDefinedAggregator" } ]

       d)运行结果:

    {"id":1,"name":"Api.Catalog1"};{"id":1,"name":"Api.Ordering"}}

    二、限流

      1、修改Route节点中的添加如下节点:

     "RateLimitOptions": {
            "ClientWhitelist": [],
            "EnableRateLimiting": true,
            "Period": "10m",
            "PeriodTimespan": 3,
            "Limit": 1
    }

      2、在GlobalConfiguration添加如下节点:

     //限流
        "RateLimitOptions": {
          "QuotaExceededMessage": "您的请求量超过了配额1/10分钟",
          "HttpStatusCode": 999
    }

      3、配置说明:

    在Route和GlobalConfiguration节点中添加了RateLimitOptions节点
    ClientWhitelist - 白名单,也就是不受限流控制的客户端
    EnableRateLimiting - 是否开启限流
    Period & Limit - 在一段时间内允许的请求次数
    PeriodTimespan - 客户端的重试间隔数,也就是客户端间隔多长时间可以重试
    QuotaExceededMessage - 限流以后的提示信息
    HttpStatusCode - 超出配额时,返回的http状态码

      4、配置说明:

        客户端在10分钟之内只允许请求一次,在请求之后3秒钟之后可以重试

    总结:

      1、请求聚合需要为每个Route设置一个Key,并设置Aggregates节点指定需要的RouteKeys。

      2、请求聚合支持自定义设置返回结果:实现IDefinedAggregator接口,并注册自定义聚合器;

      3、在需要对服务器请求进行限流时,Ocelot也能很好的支持

    后续:

      后续将对Consul介绍,并结合Ocelot使用。

  • 相关阅读:
    OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch
    带状态论文粗读(二)
    In-band Network Function Telemetry
    基于微信小程序的失物招领系统的Postmortem
    OpenStack安装
    Alpha冲刺Day12
    冲刺合集
    Alpha冲刺Day11
    Alpha冲刺总结
    测试总结
  • 原文地址:https://www.cnblogs.com/cwsheng/p/13458472.html
Copyright © 2011-2022 走看看