第六節: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 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM