NetCore Consul动态伸缩+Ocelot 网关 缓存 自定义缓存 + 限流、熔断、超时 等服务治理
网关 OcelotGeteway
网关 Ocelot配置文件
{
//===========================单地址多实例==负载均衡==Consul= 实现动态伸缩============================
"Routes": [
{
// 上游 》》 接受的请求
//上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
"UpstreamHttpMethod": [ "Get", "Post" ],
"UpstreamPathTemplate": "/P5001/{url}",
//下游》》对接受的请求 进行转发
//下游路径模板
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
//支持Consul的服务发现 的配置 就是下面的 GlobalConfiguration配置
"UseServiceDiscovery": true,
//consul的服务名称
"ServiceName": "Zen",
//能负载均衡,但是不能动态伸缩 consul
"LoadBalancerOptions": {
//RoundRobin>>轮询 LeastConnection >>最少连接数的服务器 NoLoadBalance
"Type": "RoundRobin"
}
}
],
"GlobalConfiguration": {
//网关对外地址
"BaseUrl": "Http://localhost:6299",
"ServiceDiscoveryProvider": {
"Schema": "https",
"Host": "127.0.0.1",
"Port": 8500,
"Type": "Consul" //由consul提供服务发现,每次请求去consul
}
}
}
网关以webapi 为例
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
namespace OcelotGateway
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//配置文件数据源
builder.Configuration.AddJsonFile("Configuration.json", true,true);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddOcelot()
.AddConsul();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//接受请求,转发
app.UseOcelot();
//app.UseHttpsRedirection();
//app.UseAuthorization();
//app.MapControllers();
app.Run();
}
}
}
实际的提供服务的程序 以webapi为例
ConsulHelper
public static class ConsulHelper
{
/// <summary>
/// Consul注册
/// </summary>
/// <param name="configuration"></param>
public static void ConsulRegist(this IConfiguration configuration)
{
//找Consul
ConsulClient client = new ConsulClient(c => {
c.Address = new Uri("http://localhost:8500");
c.Datacenter = "dc1";
});
string ip = string.IsNullOrWhiteSpace(configuration["ip"]) ? "localhost" : configuration["ip"];
int port = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["port"]);
int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
//唯一的
ID = "service" + Guid.NewGuid(),
//分组
Name = "Zen",
Address = ip,
Port = port,
Tags = new string[] { weight.ToString() },
//心跳
Check = new AgentServiceCheck()
{
//间隔多久一次
Interval = TimeSpan.FromSeconds(12),
//控制器
HTTP = $"http://{ip}:{port}/Api/Health/Index",
//检测等等时间
Timeout = TimeSpan.FromSeconds(5),
//失败后多久移除
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(120)
}
});
//命令行参数获取
Console.WriteLine($"注册成功:{ip}{port}-weight:{weight}");
}
}
Program 中
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Net;
using System.Text;
namespace WebAPI
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options=>
{
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "请录入Token,格式:Bearer xxxx Bearer 后面必须有个空格",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
//添加安全要求
options.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme{
Reference =new OpenApiReference{
Type = ReferenceType.SecurityScheme,
Id ="Bearer"
}
},
new string[]{ }
}});
});
// 开启Bearer 认证
builder.Services.AddAuthentication("Bearer") // 配置 JWT Bearer 选项
.AddJwtBearer("Bearer", option =>
{
option.Authority = "https://localhost:2025";
option.TokenValidationParameters = new TokenValidationParameters
{
// 验证发行者
//ValidateIssuer = true,
// 验证受众
ValidateAudience = false,
// 验证令牌有效期
//ValidateLifetime = true,
// 验证签名密钥
//ValidateIssuerSigningKey = true,
// 发行者
//ValidIssuer = builder.Configuration["TokenParameter:Issuer"],
// 受众
// ValidAudience = builder.Configuration["JokenParameter:Audience"],
// 签名密钥
//IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["TokenParameter:Secret"])),
//AudienceValidator = (m, n, z) =>
//{
// //自定义验证逻辑
// return true;
//}
};
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy(name: "ApiScope", configurePolicy: policy =>
{
//需要认证的用户
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "sample_api");
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.MapWhen(context => context.Request.Path.Equals("/api/Health/Index"),
applicationBuilder => applicationBuilder.Run(async context =>
{
Console.WriteLine($"This is Health Check");
context.Response.StatusCode = (int)HttpStatusCode.OK;
await context.Response.WriteAsync("OK");
}));
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
//程序启动时执行 ------ 且只执行一次
app.Configuration.ConsulRegist();
app.Run();
}
}
}
1、启动Consul
consul agent -dev
参考资料
2、启动webapi实际的服务
dotnet run --urls=“http://:2501" --port=2501 --ip=“localhost” --weight=2
dotnet run --urls="http://:2502” --port=2502 --ip=“localhost” --weight=2
dotnet run --urls=“http://*:2503” --port=2503 --ip=“localhost” --weight=2
3、启动网关 Ocelot
dotnet run --urls=“http://localhost:6299”
源码
网关Ocelot + Cache 缓存
》》Ocelot program
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using Ocelot.Cache.CacheManager;
namespace OcelotGateway
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//配置文件数据源
builder.Configuration.AddJsonFile("Configuration.json", true,true);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddOcelot()
.AddConsul()
.AddCacheManager(x => {
x.WithDictionaryHandle();//字典缓存
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//接受请求,转发
app.UseOcelot();
//app.UseHttpsRedirection();
//app.UseAuthorization();
//app.MapControllers();
app.Run();
}
}
}
》》》Ocelot 的配置文件
//缓存针对具体那个路由的
{
"Routes": [
{
"UpstreamPathTemplate": "/T/{url}", //上游 网关地址
"UpstreamHttpMethod": [], // 空代表任意方式 【“Get” ,"Post"】
"DownstreamPathTemplate": "/api/{url}", //服务地址>>真实的提供服务的
"DownstreamSchema": "Http",
"UseServiceDiscovery": true, //开启服务发现
"ServiceName": "Zen", //Consul 服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询 LeastConnection 》最少连接数的服务器 NoLoadBalance 不负载
},
//鉴权
//"AuthenticationOptins": {
// "AuthenticationProviderKey": "UserGatewayKey",
// "AllowedScope": []
//},
"FileCacheOptions": {
"TtlSeconds": 15, //Ttl Time To live
"Region": "UserCache" //可以调用Api缓存清理
}
}
],
"GlobalConfiguration": {
//网关对外地址
"BaseUrl": "Http://localhost:6299",
"ServiceDiscoveryProvider": {
"Schema": "https",
"Host": "127.0.0.1",
"Port": 8500,
"Type": "Consul" //由consul提供服务发现,每次请求去consul
}
//"ServiceDiscoveryProvider": {
// "Host": "localhost",
// "Port": 8500,
// "Type": "PollConsul", //由consul提供服务发现
// "PollingInterval": 1000 //轮询consul 频率毫秒--down掉是不知道的
// //“Token":"footoken"/ /需要ACL的话
//}
}
}
自定义缓存
》》》
using Consul;
using Ocelot.Cache;
namespace OcelotGateway.OcelotExtend
{
/// <summary>
/// 自定义的缓存扩展
/// </summary>
public class CustomCacheExtend : IOcelotCache<CachedResponse>
{
private readonly ILogger<CustomCacheExtend> logger;
public CustomCacheExtend(ILogger<CustomCacheExtend> logger)
{
this.logger = logger;
}
/// <summary>
/// 存放缓存数据的字典,当然可以缓存在Redis 、Mongodb
/// 可以提取出去
/// </summary>
private class CacheDataModel
{
public required CachedResponse CachedResponse { get; set; }
public DateTime Timeout { get; set; }
public string Region { get; set; }
}
private static Dictionary<string,CacheDataModel> CustomCacheExtendDictionay=new Dictionary<string,CacheDataModel>();
/// <summary>
/// 没做过期处理,所以需要
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="ttl"></param>
/// <param name="region"></param>
public void Add(string key, CachedResponse value, TimeSpan ttl, string region)
{
this.logger.LogWarning($" This is {nameof(CustomCacheExtend)}.{nameof(Add)}");
//CustomCacheExtendDictionay.Add(key, new CacheDataModel()
//{
// CachedResponse = value,
// Region = region,
// Timeout = DateTime.Now.Add(ttl)
//});
CustomCacheExtendDictionay[key] = new CacheDataModel()
{
CachedResponse = value,
Region = region,
Timeout = DateTime.Now.Add(ttl)
};
//throw new NotImplementedException();
}
public void AddAndDelete(string key, CachedResponse value, TimeSpan ttl, string region)
{
throw new NotImplementedException();
}
public void ClearRegion(string region)
{
this.logger.LogWarning($"This is {nameof(CustomCacheExtend)}.{nameof(ClearRegion)}");
var keyList=CustomCacheExtendDictionay.Where(kv=>kv.Value.Region.Equals(region)).Select(kv=>kv.Key);
foreach (var key in keyList)
{
CustomCacheExtendDictionay.Remove(key);
}
//throw new NotImplementedException();
}
public CachedResponse Get(string key, string region)
{
this.logger.LogWarning($"This is {nameof(CustomCacheExtend)}.{nameof(Get)}");
if (CustomCacheExtendDictionay.ContainsKey(key)
&& CustomCacheExtendDictionay[key] != null
&& CustomCacheExtendDictionay[key].Timeout > DateTime.Now
&& CustomCacheExtendDictionay[key].Region.Equals(region))
{
return CustomCacheExtendDictionay[key].CachedResponse;
}
else
return null;
//throw new NotImplementedException();
}
public bool TryGetValue(string key, string region, out CachedResponse value)
{
throw new NotImplementedException();
}
}
}
网关 Ocelot 服务治理》》 限流
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}", //服务地址 --url 变量
"DownstreamSchema": "http",
"UpstreamPathTemplate": "/T/{url}", //网关地址 --url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"UseServiceDiscovery": true,
"ServiceName": "zen", //Consul 服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询
},
"RateLimitOptions": {
"ClientWhitelist": [ "xx", "yy" ], //白名单 ClientId 区分大小写
"EnableRateLimiting": true,
//过期时间
"Period": "5m", //1s ,5m.1h,1d
"PeriodTimespan": 30, //多少秒之后客户端可以重试
"Limit": 5 //统计时间段内允许的最大请求数量
},
//"AuthenticationOptions": {
// "AuthenticationProviderKey": "UserGatewayKey",
// "AllowedScopes": []
//},
//"QoSOptions": {
// "ExceptionsAllowedBeforeBreaking": 3, //允许多少异常请求
// "DurationOfBreak": 10000, //熔断的时间 单位 ms
// "TimeoutValue": 2000 //单位ms 如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90s
//},
//"FileCacheOptions": {
// "TtlSeconds": 15,
// "Region": "UserCache" //可以调用Api清理
//}
}
],
"GlobalConfiguration": {
//网关对外地址
"BaseUrl": "Http://localhost:6299",
"ServiceDiscoveryProvider": {
"Schema": "https",
"Host": "127.0.0.1",
"Port": 8500,
"Type": "Consul" //由consul提供服务发现,每次请求去consul
},
"RateLimitOptions": {
"QuotaExceededMessage": "Too Many requests , maybe later ? ", //当请求过载被截断时返回的消息
"HttpStatusCode": 666 ,//当请求过载被截断时返回的http status
"ClientIdHeader": "Client_id" //用来识别客户端的请求头 , 默认是 ClientId
}
}
}
源码
Ocelot 配置文件
{
===========================单地址======================================
"Routes": [
{
// 上游 》》 接受的请求
//上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
"UpstreamHttpMethod": [ "Get", "Post" ],
"UpstreamPathTemplate": "/T5726/{url}",
//下游》》对接受的请求 进行转发
//下游路径模板
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 1005
}
]
}
]
//===========================单地址====鉴权==================================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/xx/{url}",
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/api/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1005
// }
// ],
// "AuthenticationOptins": {
// "AuthenticationProviderKey": "UserGatewayKey",
// "AllowedScopes": []
// }
// }
//]
//===========================单地址====全匹配=================================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// //冲突的还可以加权重 Priority
// "UpstreamPathTemplate": "/{url}",
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1005
// }
// ]
// }
//]
========================多地址多实例===路由冲突+权重匹配======================================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/{url}",
// "Priority": 1, //默认是0
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1005
// }
// ]
// },
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/{url}",
// "Priority": 1, //默认是0
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1006
// }
// ]
// }
//]
===========================路由冲突+权重匹配======================================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/{url}",
// "Priority": 1, //默认是0
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1005
// }
// ]
// },
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/{url}",
// "Priority": 1, //默认是0
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/{url}",
// "DownstreamScheme": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1006
// }
// ]
// }
//]
//===========================单地址多实例==负载均衡===============================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/P5001/{url}",
// //能负载均衡,但是不能动态伸缩 consul
// "LoadBalancerOptions": {
// //RoundRobin>>轮询 LeastConnection >>最少连接数的服务器 NoLoadBalance
// "Type": "RoundRobin"
// },
// //"LoadBalancerOptions": {
// // //粘粘性
// // "Type": "CookieStickySessions",
// // "Key": "Asp.Net_SessionId",
// // "Expiry": 180000
// //},
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/api/{url}",
// "DownstreamScheme": "http",
// //无法动态伸缩 ==》consul 可以
// "DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 1005
// },
// {
// "Host": "localhost",
// "Port": 1006
// },
// {
// "Host": "localhost",
// "Port": 1007
// }
// ]
// }
//]
//===========================单地址多实例==负载均衡==Consul= 实现动态伸缩============================
//"Routes": [
// {
// // 上游 》》 接受的请求
// //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "UpstreamPathTemplate": "/P5001/{url}",
// //"LoadBalancerOptions": {
// // //粘粘性
// // "Type": "CookieStickySessions",
// // "Key": "Asp.Net_SessionId",
// // "Expiry": 180000
// //},
// //下游》》对接受的请求 进行转发
// //下游路径模板
// "DownstreamPathTemplate": "/api/{url}",
// "DownstreamScheme": "http",
// //支持Consul的服务发现 的配置 就是下面的 GlobalConfiguration配置
// "UseServiceDiscovery": true,
// //consul的服务名称
// "ServiceName": "Zen",
// //能负载均衡,但是不能动态伸缩 consul
// "LoadBalancerOptions": {
// //RoundRobin>>轮询 LeastConnection >>最少连接数的服务器 NoLoadBalance
// "Type": "RoundRobin"
// }
// }
//],
//"GlobalConfiguration": {
// //网关对外地址
// "BaseUrl": "Http://localhost:6299",
// "ServiceDiscoveryProvider": {
// "Schema": "https",
// "Host": "127.0.0.1",
// "Port": 8500,
// "Type": "Consul" //由consul提供服务发现,每次请求去consul
// }
// //"ServiceDiscoveryProvider": {
// // "Host": "localhost",
// // "Port": 8500,
// // "Type": "PollConsul", //由consul提供服务发现
// // "PollingInterval": 1000 //轮询consul 频率毫秒--down掉是不知道的
// // //“Token":"footoken"/ /需要ACL的话
// //}
//}
//********************************Consul + Cache 缓存 ***************************
//"Routes": [
// {
// "UpstreamPathTemplate": "/T/{url}", //上游 网关地址
// "UpstreamHttpMethod": [], // 空代表任意方式 【“Get” ,"Post"】
// "DownstreamPathTemplate": "/api/{url}", //服务地址>>真实的提供服务的
// "DownstreamSchema": "Http",
// "UseServiceDiscovery": true, //开启服务发现
// "ServiceName": "Zen", //Consul 服务名称
// "LoadBalancerOptions": {
// "Type": "RoundRobin" //轮询 LeastConnection 》最少连接数的服务器 NoLoadBalance 不负载
// },
// //鉴权
// //"AuthenticationOptins": {
// // "AuthenticationProviderKey": "UserGatewayKey",
// // "AllowedScope": []
// //},
// "FileCacheOptions": {
// "TtlSeconds": 15, //Ttl Time To live
// "Region": "UserCache" //可以调用Api缓存清理
// }
// }
//],
//"GlobalConfiguration": {
// //网关对外地址
// "BaseUrl": "Http://localhost:6299",
// "ServiceDiscoveryProvider": {
// "Schema": "https",
// "Host": "127.0.0.1",
// "Port": 8500,
// "Type": "Consul" //由consul提供服务发现,每次请求去consul
// }
// //"ServiceDiscoveryProvider": {
// // "Host": "localhost",
// // "Port": 8500,
// // "Type": "PollConsul", //由consul提供服务发现
// // "PollingInterval": 1000 //轮询consul 频率毫秒--down掉是不知道的
// // //“Token":"footoken"/ /需要ACL的话
// //}
//}
//**************************单地址 + Ids4****************************8
//"Routes": [
// {
// "DownstreamPathTemplate": "/api/{url}", // 服务地址 --url变量
// "DownstreamSchema": "http",
// "DownstreamHostAndPorts": [
// {
// "Host": "127.0.0.1",
// "Port": 5726, //服务端口
// }
// ],
// "UpstreamPathTemplate": "/T/{url}", //官网 地址 --url变量
// "UpstreamHttpMethod": [ "Get", "Post" ],
// "AuthenticationOptions": {
// "AuthenticationProviderKey": "UserGatewayKey",
// "AllowedScopes": []
// }
// }
//]
//************************** 超时 限流 熔断 降级 Consul Polly ********************
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}", //服务地址 --url 变量
"DownstreamSchema": "http",
"UpstreamPathTemplate": "/T/{url}", //网关地址 --url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"UseServiceDiscovery": true,
"ServiceName": "zen", //Consul 服务名称
"LoadBalancerOptions": {
"Type": "RoundRobin" //轮询
},
"RateLimitOptions": {
"ClientWhitelist": [ "xx", "yy" ], //白名单 ClientId 区分大小写
"EnableRateLimiting": true,
//过期时间
"Period": "5m", //1s ,5m.1h,1d
"PeriodTimespan": 30, //多少秒之后客户端可以重试
"Limit": 5 //统计时间段内允许的最大请求数量
},
//"AuthenticationOptions": {
// "AuthenticationProviderKey": "UserGatewayKey",
// "AllowedScopes": []
//},
//"QoSOptions": {
// "ExceptionsAllowedBeforeBreaking": 3, //允许多少异常请求
// "DurationOfBreak": 10000, //熔断的时间 单位 ms
// "TimeoutValue": 2000 //单位ms 如果下游请求的处理时间超过多少则自如将请求设置为超时 默认90s
//},
//"FileCacheOptions": {
// "TtlSeconds": 15,
// "Region": "UserCache" //可以调用Api清理
//}
}
],
"GlobalConfiguration": {
//网关对外地址
"BaseUrl": "Http://localhost:6299",
"ServiceDiscoveryProvider": {
"Schema": "https",
"Host": "127.0.0.1",
"Port": 8500,
"Type": "Consul" //由consul提供服务发现,每次请求去consul
},
"RateLimitOptions": {
"QuotaExceededMessage": "Too Many requests , maybe later ? ", //当请求过载被截断时返回的消息
"HttpStatusCode": 666 ,//当请求过载被截断时返回的http status
"ClientIdHeader": "Client_id" //用来识别客户端的请求头 , 默认是 ClientId
}
}
}