.NET Core 微服务—API网关(Ocelot) 教程 [四]

摘要:
使用Ocelot的这一功能,您可以轻松实现前端/后端架构。调整后如下:{“聚合”:〔{“RouteKeys”:〔“Catalog”,“Ordering”〕,“UpstreamPathTemplate”:“/GetOrderDetail/{id}”}〕,“GlobalConfiguration”:{},“Routes”:〔{“DownstreamPathTemplate”:”/api/Values/{id}”,“发布”],“LoadBalancerOptions”:{“Type”:“RoundRobin”},“Key”:“Catalog”},{“下游PathTemplate”:“/api/Values/{id}”,“下游方案”:“http”,“下行HostAndPorts”:[{”Host“:”localhost“,”Port“:5331}],“上游PathTemplate”:“/Ordering/{id}”,“Upstream HttpMethod”:[“Get”,“Post”],“LoadBalancirOptions”“:{”Type“:”Round罗宾“},”Key“:”Ordering“}]}3。如图所示调整项目代码:返回不同的结果4访问设置的聚合地址结果如下:返回的结果是集合Key组合的数据结构。

前言:

  上一篇 介绍了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、如图调整项目代码:返回不同结果

    .NET Core 微服务—API网关(Ocelot) 教程 [四]第1张

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

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

    .NET Core 微服务—API网关(Ocelot) 教程 [四]第2张

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

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

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

    .NET Core 微服务—API网关(Ocelot) 教程 [四]第3张

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

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

    .NET Core 微服务—API网关(Ocelot) 教程 [四]第4张

  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使用。

免责声明:文章转载自《.NET Core 微服务—API网关(Ocelot) 教程 [四]》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Geoserver的rest接口使用(后台或者前端调实现自动发布服务)MySQL 8 新特性之Clone Plugin下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

调用互联网API接口(腾讯、阿里)等出现"未知名称或服务(Name or service not known)"

一、问题 开发反馈程序调用api.mch.weixin.qq.com时,时不时出现"[Errno -2] Name or service not known"错误。 二、排查 1、DNS地址配置为114.114.114.114,偶发出现解析慢的现象 2、可能原因 CentOS 6/7的DNS解析器在解析地址时会同时发出解析ipv4和ipv6的请求,且使用同...

API接口之安全篇

APP、前后端分离项目都采用API接口形式与服务器进行数据通信,传输的数据被偷窥、被抓包、被伪造时有发生,那么如何设计一套比较安全的API接口方案呢? 一般的解决方案如下: 1、Token授权认证,防止未授权用户获取数据; 2、时间戳超时机制; 3、URL签名,防止请求参数被篡改; 4、防重放,防止接口被第二次请求,防采集; 5、采用HTTPS通信协议,防...

Selenium 4以后,再不相见的API

Selenium4前线快报中提到了Selenium 4的最新进展,伴随着Selenium 4各种功能的增强,最近的版本中也包含了一些旧API的更改和启用。如果你准备从Selenium 3升级到Selenium 4,那么最好留意这些更新。 文中所列的API,看样子要跟所有Seleniumer说再见了! 弃用DesiredCapabilities 在Selen...

Spring Boot 入门系列(二十二)使用Swagger2构建 RESTful API文档

前面介绍了如何Spring Boot 快速打造Restful API 接口,也介绍了如何优雅的实现 Api 版本控制,不清楚的可以看我之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html 在实际项目中,Api 接口系统对接过程中,Api 接口文档是非常重要的文档。一般是设计完成之...

laravel添加api缓存系统

项目背景:最初是想给接口加缓存,但是不想每个接口添加缓存代码,就写了个统一的缓存系统。 技术方案: 本项目使用laravel框架 监听requestHanled事件写入缓存 添加apiCache中间件,对每个get访问进行拦截,检查是否有缓存,如果有,就读取缓存就返回,如果没有,就执行下一个中间件。 前置知识: laravel框架基础知识 event...

常见开放api平台OpenAPI

所谓的开放API(OpenAPI)是服务型网站常见的一种应用,网站的服务商将自己的网站服务封装成一系列API(Application Programming Interface,应用编程接口)开放出去,供第三方开发者使用,这种行为就叫做开放网站的API,所开放的API就被称作OpenAPI(开放API)。 网站提供开放平台的API后,可以吸引一些第三方的...