通过重写ILoadBalancer,来实现我自己想要的预发布,或者灰度发布
核心代码
/// <summary>
/// 自定义负载均衡策略
/// </summary>
public class AppLoadBalancer: ILoadBalancer
{
/// <summary>
/// 管道前面,计算到的所有下游服务
/// </summary>
private readonly Func<Task<List<Service>>> _services;
private readonly object _lock = new object();
private int _last;
public AppLoadBalancer(Func<Task<List<Service>>> services)
{
_services = services;
}
/// <summary>
/// 根据http上下文,选择合适的ServiceHostAndPort
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
public async Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
{
// 通过负载策略,以及用户的tag,导航到不同的下游服务
// 预发布、灰度发布。 逻辑都放这里了,压力过大,后期优化建议迁移出去,分开。
// 前端全量部署,或者域名划分
var down= Ocelot.Middleware.HttpItemsExtensions.DownstreamRequest(httpContext.Items);
down.Headers.Add("aa", "aaaaaaaaaaaaaaaaaaaaa");
foreach (var item in httpContext.Request.Headers)
{
Console.WriteLine($"{item.Key}>>>{item.Value}");
}
var services = await _services();
lock (_lock)
{
if (_last >= services.Count)
{
_last = 0;
}
var next = services[_last];
_last++;
return new OkResponse<ServiceHostAndPort>(next.HostAndPort);
}
}
public void Release(ServiceHostAndPort hostAndPort)
{
}
}
加入到Ocelot的LoadBalancer
Func<IServiceProvider, DownstreamRoute, IServiceDiscoveryProvider, AppLoadBalancer> loadBalancerFactoryFunc =
(serviceProvider, Route, serviceDiscoveryProvider) => new AppLoadBalancer(serviceDiscoveryProvider.Get);
services.AddOcelot().AddCustomLoadBalancer(loadBalancerFactoryFunc).AddConsul();
配置上修改负载策略,目前使用的consul来完成的,其他方式没有测试过,想实现预发布那也是需要服务注册的
( "Type": "AppLoadBalancer")
{
"DownstreamPathTemplate": "/api/{url}", //服务地址--url变量
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/not/{url}", //网关地址--url变量
"UpstreamHttpMethod": [ "Get", "Post" ],
"UseServiceDiscovery": true,
"ServiceName": "ZhaoxiService22", //consul服务名称
"LoadBalancerOptions": {
"Type": "AppLoadBalancer" //轮询 LeastConnection-最少连接数的服务器 NoLoadBalance不负载均衡
}
}
整个还没有完整的写完