本文介紹Ocelot中的QoS(Quality of Service),其使用了Polly對超時(shí)等請求下游失敗等情況進(jìn)行熔斷。
1、添加Nuget包
添加 Ocelot.Provider.Polly
到OcelotGetway項(xiàng)目中
nuget.png
2、修改 Startup.ConfigureServices
如下來添加Polly:
services
.AddOcelot(new ConfigurationBuilder()
.AddJsonFile("configuration.json")
.Build())
.AddConsul()
.AddPolly()
.AddCacheManager(x => x.WithDictionaryHandle())
.AddAdministration("/administration", "secret");
3、在WebApiA中添加一個(gè)SlowController,并添加如下代碼:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace WebApiA.Controllers
{
public class SlowController : Controller
{
[Produces("application/json")]
[Route("api/[controller]/[action]")]
public async Task<string> GetName()
{
await Task.Delay(6000);
return "Jonathan";
}
}
}
其中 GetName
延時(shí)6秒返回。
4、在configuration.json的 ReRoutes
節(jié)點(diǎn)添加一個(gè)新的路由來訪問剛才添加的api方法
{
"DownstreamPathTemplate": "/api/Slow/GetName",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/GetName",
"UpstreamHttpMethod": [ "Get" ],
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking":3,
"DurationOfBreak":60000,
"TimeoutValue": 1000
}
}
其中通過 QoSOptions
對該路由添加QoS,對其中的3個(gè)屬性解釋如下:
- ExceptionsAllowedBeforeBreaking:發(fā)生幾次請求異常(比如超時(shí))后進(jìn)行熔斷,該值必須大于0
- DurationOfBreak:熔斷時(shí)間(單位:毫秒)
- TimeoutValue:下游請求超時(shí)時(shí)間(單位:毫秒,默認(rèn)90秒)
用一句話描述上述配置:對http://localhost:5001/api/Slow/GetName請求超過1s將會超時(shí),發(fā)生三次超時(shí)后保持60s熔斷。
運(yùn)行WebApiA與OcelotGetway項(xiàng)目,然后請求http://localhost:5000/GetName多次:
QoS.GetName.gif
可以看到在前3次請求,Time在1000ms之后返回503,在第四次以后發(fā)生熔斷,請求后立即(Time在100ms左右)返回503。
官方文檔中說可以只配置TimeoutValue
而不配置其它兩個(gè)來達(dá)到修改超時(shí)時(shí)間的功能,如下:
"QoSOptions": {
"TimeoutValue":5000
}
該配置存在bug,因?yàn)槿缟吓渲?ExceptionsAllowedBeforeBreaking
將會為0,將會觸發(fā)Polly配置異常,我已經(jīng)向Ocelot提交了一個(gè)Pull Request來修復(fù)該問題,并且已經(jīng)被合并到主分支中,預(yù)計(jì)在下一個(gè)版本中該問題將不會存在。
如果你現(xiàn)在想修改超時(shí)時(shí)間,但是又不想使用熔斷,可以配置如下:
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking":10000,
"DurationOfBreak": 1,
"TimeoutValue": 1000
}
在發(fā)生很多次異常才會進(jìn)行熔斷,并且立即從熔斷中恢復(fù)。
源碼下載