一,接着前面的代碼,我們先引用Ocelot.Provider.Polly,然后我們的startup接着配置下,如下
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Ocelot.DependencyInjection; using Ocelot.Middleware; using Ocelot.Provider.Consul; using Ocelot.Provider.Polly; namespace OcelotDemo { 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) { services.AddOcelot().AddConsul().AddPolly(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseOcelot(); } } }
二,Polly之緩存設置,如下配置(緩存:就是在網關緩存請求的值,時間也是在配置中設置,本配置設置的是10S,這個適用於一般不會變化的值)
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/{url}", //服務地址--url變量 "DownstreamScheme": "http", "UpstreamPathTemplate": "/TestOcelotConsul/{url}", //網關地址--url變量 "UpstreamHttpMethod": [ "Get", "Post" ], "ServiceName": "TestConsulService", //consul服務名稱 "LoadBalancerOptions": { "Type": "RoundRobin" //輪詢 LeastConnection-最少連接數的服務器 NoLoadBalance不負載均衡 }, "UseServiceDiscovery": true, "FileCacheOptions": { "TtlSeconds": 10 //在第一次請求在網關緩存10,在十秒內怎么請求都是都網關的緩存,不會請求實例,降低壓力,提升性能 } //"緩存" } ], "GlobalConfiguration": { "BaseUrl": "http://127.0.0.1:5003", //網關對外地址 "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul" //由Consul提供服務發現 } } }
1》這個時候我們一直請求http://localhost:5003/TestOcelotConsul/user/get配置的網關地址,發現返回的都是5001接口的值,而在第10s后才會出現第二個實例的值,這個就是接口緩存,這個緩存是網關的緩存,這個減少實例的壓力,提升性能
三,Polly之限流設置,如下配置(限流:就是在設定的時間內,允許請求的次數,如果達到次數,就返回設定的信息)
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/{url}", //服務地址--url變量 "DownstreamScheme": "http", "UpstreamPathTemplate": "/TestOcelotConsul/{url}", //網關地址--url變量 "UpstreamHttpMethod": [ "Get", "Post" ], "ServiceName": "TestConsulService", //consul服務名稱 "LoadBalancerOptions": { "Type": "RoundRobin" //輪詢 LeastConnection-最少連接數的服務器 NoLoadBalance不負載均衡 }, "UseServiceDiscovery": true, "RateLimitOptions": { //限流,限制了單位時間內的訪問量 "ClientWhitelist": [], //白名單 "EnableRateLimiting": true, "Period": "5m", //1s, 5m, 1h, 1d "PeriodTimespan": 5, //多少秒之后客戶端可以重試 "Limit": 5 //統計時間段內允許的最大請求數量 } } ], "GlobalConfiguration": { "BaseUrl": "http://127.0.0.1:5003", //網關對外地址 "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul" //由Consul提供服務發現 }, "RateLimitOptions": { "QuotaExceededMessage": "Too many requests!!!!!!!", // 當請求過載被截斷時返回的消息,中文會出現亂碼 "HttpStatusCode": 503 // 當請求過載被截斷時返回的http status,經測試過超過4位的狀態碼會出現異常 } } }
1》我們請求6次這個網關地址http://localhost:5003/TestOcelotConsul/user/get,就會出現我們配置的返回信息,這里設置邏輯是五分鍾內訪問五次,第六次提示限流,在第七次我們又可以訪問,這個意思不是五分鍾內一種只能訪問五次
我們注意RateLimitOptions這個設置的值,中文和狀態碼的長度
四,Polly之熔斷設置,如下配置(熔斷:單位時間內超時,我們就直接停掉該請求返回)
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/{url}", //服務地址--url變量 "DownstreamScheme": "http", "UpstreamPathTemplate": "/TestOcelotConsul/{url}", //網關地址--url變量 "UpstreamHttpMethod": [ "Get", "Post" ], "ServiceName": "TestConsulService", //consul服務名稱 "LoadBalancerOptions": { "Type": "RoundRobin" //輪詢 LeastConnection-最少連接數的服務器 NoLoadBalance不負載均衡 }, "UseServiceDiscovery": true, "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, //允許多少個異常請求 "DurationOfBreak": 4000, // 熔斷的時間,單位為ms "TimeoutValue": 5000 //如果下游請求的處理時間超過多少則自如將請求設置為超時 默認90秒 } } ], "GlobalConfiguration": { "BaseUrl": "http://127.0.0.1:5003", //網關對外地址 "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul" //由Consul提供服務發現 } } }
我們在UserController添加一個超時的請求10000s的方法GetTimeOut
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; namespace ConsulTestDemo.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class UserController : ControllerBase { public IConfiguration _configuration; public UserController(IConfiguration configuration) { _configuration = configuration; } [HttpGet] public string Get() { return int.Parse(_configuration["port"]).ToString() + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //命令行參數必須傳入 } private static int _count = 0; [HttpGet] public string GetTimeOut() { if (int.Parse(_configuration["port"]).ToString() == "5001") { _count++; Console.WriteLine($"Get...{_count}"); if (_count <= 10) { ///這里休眠10000s實際上熔斷機制根據配置的設置,請求超時4秒就返回 System.Threading.Thread.Sleep(10000000); } ///測試在請求十次后系統修復了,又可以正常訪問 return int.Parse(_configuration["port"]).ToString() + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } else { return int.Parse(_configuration["port"]).ToString() + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //命令行參數必須傳入 } } } }
現在我們正常啟動服務和網關(看前幾篇博客啟動命令),訪問http://localhost:5003/TestOcelotConsul/user/GetTimeout網關,這個時候我們設置如果超過4s就熔斷,看我們的請求,達到四秒超時的時候直接返回了,如下圖,
我們看看正常的請求,一直在延時請求,
這個就是熔斷的區別,可以設置請求超時熔斷,避免一直占用進程,慢查詢,然后導致服務器崩潰