NetCore Ocelot 之 Aggregator

Ocelot允许声明聚合路由,把多个Routes请求batch一个对象来对客户端的请求进行响应。

1、ocelot configuration

{
      "DownstreamPathTemplate": "/api/service1",
      "DownstreamScheme": "https",
      "DownstreamHttpMethod": "Get",
      "UpstreamHttpMethod": [ "Options", "Get", "Post", "Put", "Delete" ],
      "UpstreamPathTemplate": "/Ocelot/service1",
      //"UpstreamHost": "localhost",//404 Not found
      "UseServiceDiscovery": true,
      "ServiceName": "serviceA",
      /*
      LeastConnection
      RoundRobin
      NoLoadBalance
      */
      "LoadBalancerOptions": {
        "Type": "CustomRandomLoadBalancer"
      },
      "authenticationoptions": {
        "authenticationproviderkey": "authenticationkey",
        "allowedscopes": []
      },
      "Key": "service1",
      "Priority": 11
    },
    {
      "DownstreamPathTemplate": "/api/service2",
      "DownstreamScheme": "https",
      "DownstreamHttpMethod": "Get",
      "UpstreamHttpMethod": [ "Options", "Get", "Post", "Put", "Delete" ],
      "UpstreamPathTemplate": "/Ocelot/service2",
      //"UpstreamHost": "localhost",//404 Not found
      "UseServiceDiscovery": true,
      "ServiceName": "serviceA",
      /*
      LeastConnection
      RoundRobin
      NoLoadBalance
      */
      "LoadBalancerOptions": {
        "Type": "CustomRandomLoadBalancer"
      },
      "authenticationoptions": {
        "authenticationproviderkey": "authenticationkey",
        "allowedscopes": []
      },
      "Key": "service2",
      "Priority": 12
    }
  ],
  "Aggregates": [
    {
      "RouteKeys": [
        "service1",
        "service2"
      ],
      "UpstreamPathTemplate": "/aggreate"
    }

2、创建demo NetCore API controller, service1 & service2 类似

    [Route("api/[controller]")]
    [ApiController]
    public class Service2Controller : Controller
    {
        [HttpGet]
        public IActionResult Index([FromServices] IConfiguration configuration)
        {
            var result = new
            {
                msg = $"This is service2, current date: {DateTime.Now:G}",
                ip = configuration["ip"],
                port = configuration["port"]
            };
            return new JsonResult(result);
        }
    }

3、执行结果

 

 

如何自定义聚合,在Aggregate节点添加Aggregator配置

 "Aggregates": [
    {
      "RouteKeys": [
        "service1",
        "service2"
      ],
      "UpstreamPathTemplate": "/aggreate",
      "Aggregator": "CustomAdvancedAggregator"
    }
  ]
builder.Services.AddOcelot()
    .AddSingletonDefinedAggregator<CustomAdvancedAggregator>()
    .AddCustomLoadBalancer((serviceProvider, route, serviceDiscoveryProvider) => new CustomRandomLoadBalancer(serviceDiscoveryProvider.Get))
    .AddConsul()
    .AddPolly();
 public class CustomAdvancedAggregator : IDefinedAggregator
    {
        public CustomAdvancedAggregator() { }

        public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
        {
            var stringContent = new List<string>();
            foreach (var response in responses)
            {
                byte[] bytes = new byte[response.Response.Body.Length];
                await response.Response.Body.ReadAsync(bytes, 0, bytes.Length);
                var content = Encoding.UTF8.GetString(bytes);
                stringContent.Add(content);
            }
            var headers = responses.SelectMany(r => r.Response.Headers.Select(h => new Header(h.Key, h.Value))).Distinct().ToList();
            var downstreamResponse = new DownstreamResponse(new StringContent(String.Join(";",stringContent)), System.Net.HttpStatusCode.OK, headers, "custom aggregate");
            return downstreamResponse;
        }
    }

 

OK, 搞定!

posted @ 2023-03-04 09:36  云霄宇霁  阅读(42)  评论(0编辑  收藏  举报