环境:
- window10 x64 企业版
- vs2019 企业版 16.7.5
- Ocelot.Provider.Polly 16.0.1
实验代码下载:https://download.csdn.net/download/u010476739/13038228
一、实验的介绍和架构图
首先什么是熔断?
答:网关对后台服务的一种出错保护机制,就是当后台服务屡次出错后就直接将服务关停一会。
后台服务在熔断中的几个状态:
后台服务处于三个状态之一:正常状态、熔断状态和半熔断状态。
-
正常状态
:
这个就是服务表现良好,没有出现问题,一切ok。 -
熔断状态
:
后台服务屡次超时(注意:这里是超时,不是后台服务报500),ocelot网关发现后就将这个服务标记为熔断状态
并设置一个状态持续时间,在这个状态持续时间内,所有发往服务A的请求都会直接返回503(Service Unavailable)。 -
半熔断状态
:
当后台服务度过了熔断的持续时间后,ocelot就会将这个服务标记为半熔断状态
,之后这个服务处理的第一个请求会被ocelot观察,如果第一个请求处理正常,那么将这个服务标记为正常状态
,否则将这个服务重新标记为熔断状态
并设置状态持续时间。
这三个状态之间的转换如下所示:
本次实验的架构如下:
二、准备OrderApi
工程
新建空白解决方案ocelot-qos-trial
,然后新建OrderApi
工程。
给OrderApi
工程添加控制器,如下:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Threading;
namespace OrderApi.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class DemoController : ControllerBase
{
private readonly IConfiguration configuration;
public DemoController(IConfiguration configuration)
{
this.configuration = configuration;
}
[HttpGet]
public string Get()
{
var urls = configuration["urls"];
Thread.Sleep(6000);
return $"from {urls}";
}
}
}
修改appsettings.json
配置文件,设定运行端口为5501:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
编译后直接运行即可!
三、准备ocelot-qos-trial
工程
在ocelot-qos-trial
解决方案上,新建ocelot-qos-trial
工程。
引入Ocelot.Provider.Polly
包:
<ItemGroup>
<PackageReference Include="Ocelot.Provider.Polly" Version="16.0.1" />
</ItemGroup>
添加配置文件ocelot.json
(注意将这个文件设置复制到输出目录):
{
"Routes": [
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/order/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5501
}
],
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 2, // 多少个超时请求会触发熔断
"DurationOfBreak": 5000, // 熔断的持续时间,单位为毫秒
"TimeoutValue": 3000 // 如果下游请求的处理时间超过多少则视如该请求超时,单位为毫秒
}
}
],
"GlobalConfiguration": {}
}
修改Program.cs
,引入ocelot.json文件配置:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace OrderApi
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(conf =>
{
conf.AddJsonFile("ocelot.json");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
修改Startup.cs
文件,引入ocelot
功能:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Polly;
namespace ocelot_qos_trial
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot().AddPolly();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseOcelot().Wait();
}
}
}
最后,修改appsettings.json
文件,指定运行端口5500:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"urls": "https://localhost:5500/"
}
编译后,直接运行即可!
四、测试熔断效果
根据配置和代码,我们期待的效果是这样的:
我们连续两次请求服务,因为此时还未触发熔断,所以这两个请求都要持续3秒多一点并且返回的是503(已经超时了)。而此时的ocelot已经触发的熔断机制,将
OrderApi
标记为熔断状态
。
我们迅速的发起第3次请求(第二次请求和第三次请求之间不要超过5秒),发现后台直接给我们返回503,而不是等待3秒。
然后,我们稍等一会(大概有5秒,5秒后后台服务应该被标记为半熔断状态
),再次发起第4次请求,这次我们要等待3秒多一点接受到返回的503。注意,此时因为处于半熔断状态
下的后台服务又一次处理超时了,所以服务又重新回到了熔断状态。
然后,我们迅速发起第5个请求,我们发现后台马上返回了503。
然后。。。
实验中的过程如下: