第六节:Ocelot之自身负载、网关限流、缓存和熔断机制

一. 自身负载

1. 含义

 实现Ocelot转发多个业务服务器,不去Consul中获取,直接在配置文件中配置。

 LoadBalancer将决定负载均衡的算法

  - LeastConnection – 将请求发往最空闲的那个服务器

  - RoundRobin – 轮流发送

  - NoLoadBalance – 总是发往第一个请求或者是服务发现

2. 用到的项目

 OcelotGateWay:网关

 GoodsService:业务服务器

 OrderService:业务服务器

3. 测试步骤

(1).启动Consul,【consul.exe agent -dev】,因为业务服务器中进行了服务注册,与Ocelot无关

(2).启动网关:【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020 】

    其中GoodsService配置LeastConnection算法,OrderService配置RoundRobin算法。

配置文件

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7001
        },
        {
          "Host": "127.0.0.1",
          "Port": 7002
        },
        {
          "Host": "127.0.0.1",
          "Port": 7003
        }
      ],
      "UpstreamPathTemplate": "/GoodsService/{url}",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"     //轮询
      },
      "UpstreamHttpMethod": [ "Get", "Post" ]
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7004
        },
        {
          "Host": "127.0.0.1",
          "Port": 7005
        },
        {
          "Host": "127.0.0.1",
          "Port": 7006
        }
      ],
      "UpstreamPathTemplate": "/OrderService/{url}",
      "LoadBalancerOptions": {
        "Type": "LeastConnection"   //最少连接数
      },
      "UpstreamHttpMethod": [ "Get", "Post" ]
    }
  ]
}
View Code

(3).启动业务服务器:GoodsService对应7001、7002、7003端口,OrderService对应7004、7005、7006端口

  dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001

  dotnet GoodsService.dll --urls="http://*:7002" --ip="127.0.0.1" --port=7002

  dotnet GoodsService.dll --urls="http://*:7003" --ip="127.0.0.1" --port=7003

  dotnet OrderService.dll --urls="http://*:7004" --ip="127.0.0.1" --port=7004

  dotnet OrderService.dll --urls="http://*:7005" --ip="127.0.0.1" --port=7005

  dotnet OrderService.dll --urls="http://*:7006" --ip="127.0.0.1" --port=7006

(4). PostMan测试: Get测试: http://127.0.0.1:7020/GoodsService/Catalog/GetGoodById1?id=123,多次请求,如图一

         Post请求:http://127.0.0.1:7020/OrderService/Buy/pOrder1 ,多次请求,如图二

图一:

图二:

 

 

二. 限流

1. 含义

 可以限制一段时间内请求数量,当超过这个数量,则截断请求不进行转发。

2. 核心配置剖析

(1). Routes下的配置

"RateLimitOptions": {
    "ClientWhitelist": [],
    "EnableRateLimiting": true,
    "Period": "10s",
    "PeriodTimespan": 10,
    "Limit": 2
}

  - ClientWihteList 白名单

  - EnableRateLimiting 是否启用限流

  - Period 统计时间段:1s, 5m, 1h, 1d

  - PeroidTimeSpan 多少秒之后客户端可以重试

  - Limit 在统计时间段内允许的最大请求数量

(2).全局配置

"GlobalConfiguration": {
    "RateLimitOptions": {
    "DisableRateLimitHeaders": false,
    "QuotaExceededMessage": "您访问的网站流量处于流量高峰期,您的请求被截断了",
    "HttpStatusCode": 888,
    "ClientIdHeader": "xxxxx1"
    }
}

  - DisableRateLimitHeaders:Http头 X-Rate-Limit 和 Retry-After是否禁用。

  - QuotaExceedMessage 当请求过载被截断时返回的消息。

  - HttpStatusCode 当请求过载被截断时返回的http status。

  - ClientIdHeader 用来识别客户端的请求头,默认是 ClientId。

核心配置分享:

{
  "Routes": [
    {
      //转发下游(业务服务器)的匹配规则
      "DownstreamPathTemplate": "/api/{url}",
      //下游请求类型
      "DownstreamScheme": "http",
      //下游的ip和端口,和上面的DownstreamPathTemplate匹配起来
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7001
        }
      ],
      //上游(即Ocelot)接收规则
      "UpstreamPathTemplate": "/GoodsService/{url}",
      //上游接收请求类型
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "RateLimitOptions": {
        "ClientWhitelist": [],
        "EnableRateLimiting": true,
        "Period": "10s",
        "PeriodTimespan": 10,
        "Limit": 2
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7004
        }
      ],
      "UpstreamPathTemplate": "/OrderService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ]
    }
  ],
  //全局配置
  "GlobalConfiguration": {
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "您访问的网站流量处于流量高峰期,您的请求被截断了",
      "HttpStatusCode": 888,
      "ClientIdHeader": "xxxxx1"
    }
  }
}
View Code

3. 测试

(1). 启动网关:【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020 】

(2). 启动业务服务器:【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001 】

(3). PostMan测试: Get测试: http://127.0.0.1:7020/GoodsService/Catalog/GetGoodById1?id=123, 快速点击到第三次

A.不使用全局配置的情况如下图:

B.使用全服配置的情况如下图:

 

 

 

三. 缓存

1. 含义

 Ocelot可以对下游请求结果进行缓存 ,目前缓存的功能还不是很强大。它主要是依赖于[CacheManager](https://github.com/MichaCo/CacheManager) 来实现的。

2. 核心配置

(1).通过Nuget安装  Ocelot.Cache.CacheManager.【16.0.1】

(2).在Routes中配置:

"FileCacheOptions": {
    "TtlSeconds": 15, //过期时间(秒)
    "Region": "00001" //缓存分区名称
}

(3).ConfiguereSevice中配置:AddCacheManager(x =>{ x.WithDictionaryHandle();});

核心配置:

{
  "Routes": [
    {
      //转发下游(业务服务器)的匹配规则
      "DownstreamPathTemplate": "/api/{url}",
      //下游请求类型
      "DownstreamScheme": "http",
      //下游的ip和端口,和上面的DownstreamPathTemplate匹配起来
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7001
        }
      ],
      //上游(即Ocelot)接收规则
      "UpstreamPathTemplate": "/GoodsService/{url}",
      //上游接收请求类型
      "UpstreamHttpMethod": [ "Get", "Post" ],
      //缓存
      "FileCacheOptions": {
        "TtlSeconds": 15,
        "Region": "00001"
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7004
        }
      ],
      "UpstreamPathTemplate": "/OrderService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ]
    }
  ]
}
View Code

Startup:

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //1.注册Ocelot
            var ocelot = services.AddOcelot();
            //2. 给Ocelot注册Consul支持  (或者和上面写一起:services.AddOcelot().AddConsul();)
            ocelot.AddConsul();

            //3.给Ocelot添加缓存支持
            ocelot.AddCacheManager(x =>
            {
                x.WithDictionaryHandle();
            });
 
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //1.使用Ocelot
            app.UseOcelot().Wait();    //这里不写异步用法了

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
View Code

Api方法:

        /// <summary>
        /// 测试Ocelot的缓存机制
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public string TestCache()
        {
            Random r = new Random();
            var d1 = r.Next(1, 100000);
            var d2 = Guid.NewGuid().ToString("N");

            return $"返回值为:d1={d1},d2={d2}";
        }
View Code

3. 测试

(1). 启动网关:【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020 】

(2). 启动业务服务器:【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001 】

          并在其中增加一个新的测试方法:TestCache,每次返回不同的随机数

(3). PostMan测试: Get测试: http://127.0.0.1:7020/GoodsService/Catalog/TestCache, 快速点击,发现返回值不变,15s后,产生了新的返回。

相关截图如下:

 

四. 熔断机制

1. 含义

  熔断的意思是停止将请求转发到下游服务。当下游服务已经出现故障的时候再请求也是功而返,并且会增加下游服务器和API网关的负担。

2. 核心配置

(1). 通过Nuget安装 Ocelot.Provider.Polly. 【16.0.1】

(2). 在Routes配置:

"QoSOptions": {
  "ExceptionsAllowedBeforeBreaking": 3, //允许异常请求的个数
  "DurationOfBreak": 10000, //熔断时间(毫秒)
  "TimeoutValue": 5000 //如果下游请求的处理时间超过多少则自动将请求设置为超时
}

(3).ConfiguereSevice中配置:ocelot.AddPolly();

核心配置:

{
  "Routes": [
    {
      //转发下游(业务服务器)的匹配规则
      "DownstreamPathTemplate": "/api/{url}",
      //下游请求类型
      "DownstreamScheme": "http",
      //下游的ip和端口,和上面的DownstreamPathTemplate匹配起来
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7001
        }
      ],
      //上游(即Ocelot)接收规则
      "UpstreamPathTemplate": "/GoodsService/{url}",
      //上游接收请求类型
      "UpstreamHttpMethod": [ "Get", "Post" ],
      //熔断机制
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3, //允许异常请求的个数
        "DurationOfBreak": 10000,      //熔断时间(毫秒)
        "TimeoutValue": 5000        //如果下游请求的处理时间超过多少则自动将请求设置为超时
      }
    },
    {
      "DownstreamPathTemplate": "/api/{url}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "127.0.0.1",
          "Port": 7004
        }
      ],
      "UpstreamPathTemplate": "/OrderService/{url}",
      "UpstreamHttpMethod": [ "Get", "Post" ]
    }
  ]
}
View Code

Startup类:

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //1.注册Ocelot
            var ocelot = services.AddOcelot();
            //2. 给Ocelot注册Consul支持  (或者和上面写一起:services.AddOcelot().AddConsul();)
            ocelot.AddConsul();
            //4.给Ocelot添加熔断机制
            ocelot.AddPolly();

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //1.使用Ocelot
            app.UseOcelot().Wait();    //这里不写异步用法了

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
View Code

3. 测试

(1).启动网关:【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020 】

(2).不启动业务服务,也就是模拟业务服务器宕机的情况

(3).PostMan测试: Get测试: http://127.0.0.1:7020/GoodsService/Catalog/TestCache

  A.快速点击3次,返回状态码为502 Bad Gateway

  B.接着点击,返回状态码为503Service Unavailable,且是瞬间返回,说明已经熔断了

  C.10秒后,再次点击,接着又是502 Bad Gateway

 

 

 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

 

posted @ 2020-07-15 18:02  Yaopengfei  阅读(901)  评论(2编辑  收藏  举报