API网关—Ocelot之负载均衡
- 负载均衡
- 请求缓存
负载均衡
分布式架构中,当后端同一个应用的实例较多,负载均衡是非常必要的,否则前端对后端API的请求,可能只命中其中的几个应用实例,这几个实例压力会很大,而其他实例一直处于空闲状态,达不到分布式架构中利用服务器资源换取性能的效果。
Ocelot网关提供了负载均衡功能,通过配置文件即可实现,下面是Ocelot负载均衡功能的demo。
- 启动CustomerService的两个实例,修改以下之前的演示api让其放回不同的结果
启动实例1: - 启动实例2:
- 在nacos也可以看到注册上了CustomerService的两个实例
- 在nacos也可以看到注册上了CustomerService的两个实例
- 修改Ocelot网关配置
负载均衡主要配置LoadBalancerOptions节点,可以配置在Routes节点各个服务路由中,这将对单个服务起作用,也可以配置在GlobalConfiguration中,官方文档中说明GlobalConfiguration中的配置,将会覆盖Routes中各个路由的配置,但是17.0.1版本下经过测试发现并不起作用,在Routes节点有配置的情况下,必须针对每个服务进行配置,无法通过全局配置作用于所有的服务。
这里我依旧沿用上一节的动态路由,在Routes节点没有内容的情况下,在GlobalConfiguration中配置LoadBalancerOptions是可以的。
"GlobalConfiguration": {
"RequestIdKey": null,
"ServiceDiscoveryProvider": {
"Type": "Nacos",
// 为了使用动态路由必须配置Host和Port,查看DownstreamRouteFinderMiddleware中的IDownstreamRouteProviderFactory获取时,
// 只有存在Host和Port的时候,才会获取到DownstreamRouteCreator,才能从url中解析出ServiceName
"Host": "0.0.0.0",
"Port": 8500
},
"DownstreamScheme": "http",
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
Ocelot负载均衡策略提供四种默认的方式
○ RoundRobin
○ LeastConnection
○ NoLoadBalance
○ CookieStickySessions
- 通过网关访问CustomerService的API
启动Ocelot网关,测试负载均衡 - 扩展负载均衡策略
如果觉得Ocelot提供的负载均衡策略不足以满足自己在工作的实际需求,Ocelot也支持自定义负载均衡策略。
(1) 实现ILoadBalancer接口,实现自己的负载均衡策略逻辑
/// <summary>
/// 自定义负载均衡策略
/// </summary>
public class CustomerBalancer : ILoadBalancer
{
private readonly Func<Task<List<Service>>> _services;
private readonly object _lock = new object();
private int _last;
public CustomerBalancer(Func<Task<List<Service>>> services)
{
_services = services;
}
public async Task<Response<ServiceHostAndPort>> Lease(HttpContext httpContext)
{
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)
{
}
}
这里是轮询策略的实现的实现,只是一个演示。
(2) 将自定义负载均衡策略加入Ocelot依赖中
Func<IServiceProvider, DownstreamRoute, IServiceDiscoveryProvider, CustomerBalancer> loadBalancerFactoryFunc = (serviceProvider, Route, serviceDiscoveryProvider) => new CustomerBalancer(serviceDiscoveryProvider.Get);
services.AddOcelot(Configuration)
.AddNacosDiscovery()
.AddCustomLoadBalancer(loadBalancerFactoryFunc);
(3) 配置文件中负载均衡策略改为我们自己的类型
"LoadBalancerOptions": {
"Type": "CustomerBalancer"
}
请求缓存
有些时候,为了提供API接口的访问速度,我们可能会将某些API接口的结果进行缓存,Ocelot网关也提供了这样的功能,通过FileCacheOptions配置对下游服务的URL进行缓存,目前只支持get方式,只要请求的URL不变,就会缓存。FileCacheOptions需要配置在Routes中的某个节点,在动态路由的情况下是不支持的。
"Routes": [
{
"UpstreamPathTemplate": "/Customer/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"UseServiceDiscovery": true,
"ServiceName": "customerService",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"FileCacheOptions": {
"TtlSeconds": 5,
"Region": "somename"
}
}
]
TtlSeconds是缓存时间,单位是秒,Region是缓存域,可以通过调用Ocelot的管理API来清除某个Region的缓存。
微服务系列文章:
上一篇:API网关—Ocelot之服务发现 下一篇:API网关—Ocelot之限流熔断