zoukankan      html  css  js  c++  java
  • 第六节: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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    No Hibernate Session bound to thread, and configuration does not allow
    谈谈数据库中MyISAM与InnoDB区别
    hibernate实体的几种状态:
    解决Eclipse导出javadoc乱码问题
    freemarker截取字符串
    many-to-one和one-to-many的配置比较
    one-to-many many-to-one配置解释
    extends:类似于java中的继承特征,extends="struts-default"
    eclipse 中创建maven web项目
    java.lang.ClassNotFoundException: javax.persistence.EntityListeners
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/13307065.html
Copyright © 2011-2022 走看看