API网关—Ocelot之负载均衡

本文介绍了Ocelot作为API网关如何实现负载均衡,包括RoundRobin、LeastConnection等策略,并展示了自定义负载均衡策略的步骤。同时,讲解了Ocelot的请求缓存功能,通过FileCacheOptions配置实现对下游服务的缓存,提高接口访问速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API网关—Ocelot之负载均衡

1. 负载均衡

分布式架构中,当后端同一个应用的实例较多,负载均衡是非常必要的,否则前端对后端 API 的请求,可能只命中其中的几个应用实例,这几个实例压力会很大,而其他实例一直处于空闲状态,达不到分布式架构中利用服务器资源换取性能的效果。

Ocelot 网关提供了负载均衡功能,通过配置文件即可实现,下面是 Ocelot 负载均衡功能的 demo。

  1. 启动 CustomerService 的两个实例,修改以下之前的演示 api 让其返回不同的结果

    启动实例1:
    在这里插入图片描述
    在这里插入图片描述
    启动实例2:
    在这里插入图片描述
    在这里插入图片描述
    在 Nacos 也可以看到注册上了 CustomerService 的两个实例
    在这里插入图片描述

  2. 修改 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
  3. 通过网关访问 CustomerService 的 API

    启动 Ocelot 网关,测试负载均衡
    在这里插入图片描述

  4. 扩展负载均衡策略

    如果觉得 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"
     }
    

2. 请求缓存

有些时候,为了提升 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之限流熔断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值