一. 自身負載
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" ] } ] }
(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" } } }
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" ] } ] }
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(); }); } }
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}"; }
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" ] } ] }
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(); }); } }
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 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。