.Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换

1.什么是API网关

API网关是微服务架构中的惟一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API。它能够具备身份验证,监控,负载均衡,缓存,请求分片与管理,静态响应处理等。API网关方式的核心要点是,全部的客户端和消费端都经过统一的网关接入微服务,在网关层处理全部的非业务功能。一般,网关也是提供REST/HTTP的访问API。服务端经过API-GW注册和管理服务。git

Ocelot介绍

Ocelot是用.net Core实现的一款开源的网关,Ocelot其实就是一组按照顺序排列的.net core中间件。它接受到请求以后用request builder构建一个HttpRequestMessage对象并发送到下游服务,当下游请求返回到Ocelot管道时再由一个中间件将HttpRequestMessage映射到HttpResponse上返回客户端。github

开源地址点击这里web

使用Ocelot傻瓜式转发

新建三个项目webApi项目,分别命名为ApiGateway,Api_A,Api_B算法

ZFGUV6N4@P[]DTRP`0CI5T8.png
  
设置Api_A端口为5001,Api_B端口为5002,ApiGateway为5000json

为ApiGateway项目安装Ocelot,在Nuget中搜索Ocelot或者直接使用Install-Package Ocelot进行安装。最新版本为13.8.x支持core3.0。api

在ApiGateway新建一个configuration.json配置文件。缓存

{
  "ReRoutes": [
    {
      //上游Api请求格式
      "UpstreamPathTemplate": "/Api_A/{controller}/{action}",
      //网关转发到下游格式
      "DownstreamPathTemplate": "/api/{controller}/{action}",
      //上下游支持请求方法
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "DownstreamScheme": "http",
      //下游服务配置
      "DownstreamHostAndPorts": [
        {
          //下游地址
          "Host": "localhost",
          //下游端口号
          "Port": 5001
        }
      ]
    },
    {
      "UpstreamPathTemplate": "/Api_B/{controller}/{action}",
      "DownstreamPathTemplate": "/api/{controller}/{action}",
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5002
        }
      ]
    }
  ]
}

Startup.csConfigureServicesConfigure中配置Ocelot服务器

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddOcelot(new ConfigurationBuilder()
      .AddJsonFile("configuration.json")
      .Build());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseOcelot();
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseMvc();
}

分别为Api_A,和Api_B分别添加一个print接口。架构

[HttpGet("print")]
public string Print()
{
    return "Api_A";
}
[HttpGet("print")]
public string Print()
{
    return "Api_B";
}

测试网关

启动三个项目,使用postman来调用网关并发

访问Api_A服务
20191128111219.png

访问Api_B服务

20191128111321.png

能够看到网关经过接受到的请求的Url后经过咱们的配置自动转发到了咱们想要访问的服务。

网关的负载均衡

当下游拥有多个节点的时候,咱们能够用DownstreamHostAndPorts来配置

{
    "UpstreamPathTemplate": "/Api_A/{controller}/{action}",
    "DownstreamPathTemplate": "/api/{controller}/{action}",
    "DownstreamScheme": "https",
    "LoadBalancer": "LeastConnection",
    "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
    "DownstreamHostAndPorts": [
            {
                "Host": "127.0.0.1",
                "Port": 5001,
            },
            {
                "Host": "127.00.1",
                "Port": 5002,
            }
        ],
}

LoadBalancer是来决定负载的算法

  • LeastConnection:将请求发往最空闲的那个服务器
  • RoundRobin:轮流转发
  • NoLoadBalance:老是发往第一个请求或者是服务发现

限流

限流能够防止上下游服务器由于过载而崩溃,可使用RateLimitOptions来配置限流

{
    "RateLimitOptions": {
        "ClientWhitelist": [“127.0.0.1”],
        "EnableRateLimiting": true,
        "Period": "5s",
        "PeriodTimespan": 1,
        "Limit": 10
    }
}
  • ClientWihteList:白名单,不受限流控制。
  • EnableRateLimiting:使用启用限流。
  • Period:限流控制的时间段 1s, 5m, 1h, 1d。
  • PeroidTimeSpan:超过限流限制的次数后,须要等待重置的时间(单位是秒)。
  • Limit:在限流控制时间段内最大访问数。
    对于除了请求头中ClientId=127.0.0.1的意外全部求情启用限流,5秒该api最多10次,若是达到10次须要从第10次请求闭合后等待一秒进行下一次访问。

超过限流后会返回429状态码,并在在返回头(Response Header)的Retry-After属性中返回等待重置时间。
20191209113242.png
20191209113333.png
限流的默认提示,code码,和限制标志都是能够本身配置的

{ 
  "GlobalConfiguration": {
    "BaseUrl":"www.baidu.com",
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "接口限流!",
      "HttpStatusCode": 200,
      "ClientIdHeader": "ClientId"
    }
  }

20191209114201.png

  • DisableRateLimitHeaders:是否显示X-Rate-Limit和Retry-After头
  • QuotaExceededMessage:提示信息
  • HttpStatusCode:状态码
  • ClientIdHeader:用来设别客户请求头,默认为ClientId。
  • BaseUrl 网关暴露的的地址。

熔断

熔断是在下游服务故障或者请求无响应的时候中止将请求转发到下游服务。

{ 
    "QoSOptions": {
    "ExceptionsAllowedBeforeBreaking": 3,
    "DurationOfBreak": 20,
    "TimeoutValue": 5000
    }
}
  • ExceptionsAllowedBeforeBreaking:容许多少个异常请求。
  • DurationOfBreak:熔断的时间(秒)。
  • TimeoutValue:下游请求的处理时间超过多少则将请求设置为超时。

缓存

Ocelot能够对下游请求结果进行缓存,主要是依赖于CacheManager来实现的。

{
    "FileCacheOptions": {
        "TtlSeconds": 60,
        "Region": "key"
    }
}
  • TtlSeconds:缓存时间(秒)。
  • Region:缓存分区名
    咱们能够调用Ocelot的API来移除某个区下面的缓存 。

请求头的转化

Ocelot容许在请求下游服务以前和以后转换Header.目前Ocelot只支持查找和替换.

若是们须要转发给下游的Header重添加一个key/value

{
    "UpstreamHeaderTransform": {
        "demo": "xxxxxxx"
    }
}

若是们须要在返回给客户端的的Header中添加一个key/value

{
    "DownstreamHeaderTransform": {
        "demo": "xxxxxxx"
    }
}

若是咱们须要替换Heaher中某些值

{
    //请求
    "UpstreamHeaderTransform": {
        "demo": "a,b"
    },
    //响应
    "DownstreamHeaderTransform":
    {
        "demo": "a,b"
    }
}

语法是{find},{replace}, 利用b取代a

在Header转换中可使用占位符

  • {BaseUrl} - 这个是Ocelot暴露在外的url. 例如http://localhost:5000/.
  • {DownstreamBaseUrl} - 这个是下游服务的基本url 例如http://localhost:5001/. 目前这个只在DownstreamHeaderTransform中起做用.
  • {TraceId} - 这个是Butterfly的跟踪id.目前这个也只在DownstreamHeaderTransform中起做用

若是您想将location头返回给客户端,可能须要将location更改成Ocelot的地址而不是下游服务地址。 Ocelot可使用如下配置实现。

{
    "DownstreamHeaderTransform": {
    "Location": "{DownstreamBaseUrl},{BaseUrl}"
    },
}

给Header中添加下游地址
20191209162057.png

响应的Header中已经替换成BaseUrl了
20191209162154.png

总结

简单的实现了经过网关来访问api接口。ocelot功能远不止这些,以后会实现与IdentityServer的认证鉴权。服务发现。

相关文章
相关标签/搜索