针对 Ocelot 网关的性能测试

发表于:2019-2-20 10:27

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:myzony    来源:博客园

  一、背景
  目前我们项目是采用的 Ocelot 作为 API 网关,并且在其基础上结合 IdentityServer4 开发了一套 API 开放平台。由于部分项目是基于 ABP 框架进行开发的,接口的平均 QPS 基本是在 2K~3K /S 左右 (E3 1231 16G)。采用 Ocelot 进行请求转发之后,前端反馈接口调用速度变慢了,也没有太过在意,以为是项目接口的问题,一直在接口上面尝试进行优化。
  极限优化接口后仍然没有显著改善,故针对 Ocelot 的性能进行压力测试,得到的结果也是让我比较惊讶。
  二、准备工作
  2.1 测试项目准备
  首先新建了一个解决方案,其名字为 OcelotStudy ,其下面有三个项目,分别是两个 API 项目和一个网关项目。
  网关项目编写:
  为 OcelotStudy 项目引入 Ocelot 的 NuGet 包。
  在 OcelotStudy 项目的 Program.cs 文件当中显式指定我们网关的监听端口。
   using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Hosting;
  namespace OcelotStudy
  {
  public class Program
  {
  public static void Main(string[] args)
  {
  CreateHostBuilder(args).Build().Run();
  }
  public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
  .ConfigureWebHostDefaults(webBuilder =>
  {
  // 指定监听端口为 5000
  webBuilder.UseStartup<Startup>()
  .UseKestrel(x=>x.ListenAnyIP(5000));
  });
  }
  }
  在 Startup.cs 类当中注入 Ocelot 的服务,并应用 Ocelot 的中间件。
   using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Logging;
  using Ocelot.DependencyInjection;
  using Ocelot.Middleware;
  namespace OcelotStudy
  {
  public class Startup
  {
  public void ConfigureServices(IServiceCollection services)
  {
  // 禁用日志的控制台输出,防止由于线程同步造成的性能损失
  services.AddLogging(op => op.ClearProviders());
  services.AddMvc();
  services.AddOcelot(new ConfigurationBuilder().AddJsonFile("Ocelot.json").Build());
  }
  public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
  await app.UseOcelot();
  app.UseMvc();
  }
  }
  }
  在 OcelotStudy 项目下建立 Ocelot.json 文件,内容如下。
   {
  "ReRoutes": [
  {
  "DownstreamPathTemplate": "/api/{everything}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
  {
  "Host": "localhost",
  "Port": 6000
  },
  {
  "Host": "localhost",
  "Port": 7000
  }
  ],
  "UpstreamPathTemplate": "/{everything}",
  "UpstreamHttpMethod": [ "Get", "Post" ],
  "LoadBalancerOptions": {
  "Type": "RoundRobin"
  }
  }
  ],
  "GlobalConfiguration": {
  }
  }
  测试项目的编写:
  两个测试项目的监听端口分别为 6000 与 7000 ,都建立一个 ValuesController 控制器,返回一个字符串用于输出当前请求的 API 服务器信息。
  ApiService01 的文件信息:
   using Microsoft.AspNetCore.Mvc;
  namespace ApiService01.Controllers
  {
  [Route("api/[controller]")]
  [ApiController]
  public class ValuesController : ControllerBase
  {
  // GET api/values
  [HttpGet]
  public ActionResult<string> Get()
  {
  return "当前请求的 API 接口是 1 号服务器。";
  }
  // GET api/values/5
  [HttpGet("{id}")]
  public ActionResult<string> Get(int id)
  {
  return "value";
  }
  // POST api/values
  [HttpPost]
  public void Post([FromBody] string value)
  {
  }
  // PUT api/values/5
  [HttpPut("{id}")]
  public void Put(int id, [FromBody] string value)
  {
  }
  // DELETE api/values/5
  [HttpDelete("{id}")]
  public void Delete(int id)
  {
  }
  }
  }
  ApiService02 的文件信息:
   using Microsoft.AspNetCore.Mvc;
  namespace ApiService02.Controllers
  {
  [Route("api/[controller]")]
  [ApiController]
  public class ValuesController : ControllerBase
  {
  // GET api/values
  [HttpGet]
  public ActionResult<string> Get()
  {
  return "当前请求的 API 接口是 2 号服务器。";
  }
  // GET api/values/5
  [HttpGet("{id}")]
  public ActionResult<string> Get(int id)
  {
  return "value";
  }
  // POST api/values
  [HttpPost]
  public void Post([FromBody] string value)
  {
  }
  // PUT api/values/5
  [HttpPut("{id}")]
  public void Put(int id, [FromBody] string value)
  {
  }
  // DELETE api/values/5
  [HttpDelete("{id}")]
  public void Delete(int id)
  {
  }
  }
  }
  他们两个的 Startup.cs 与 Program.cs 文件内容基本一致,区别只是监听的端口分别是 6000 和 7000 而已。
   using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Hosting;
  namespace ApiService02
  {
  public class Program
  {
  public static void Main(string[] args)
  {
  CreateHostBuilder(args).Build().Run();
  }
  public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
  .ConfigureWebHostDefaults(webBuilder =>
  {
  webBuilder.UseStartup<Startup>();
  webBuilder.UseKestrel(x => x.ListenAnyIP(6000)); // 或者 7000
  });
  }
  }
  
   using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Logging;
  namespace ApiService02
  {
  public class Startup
  {
  public Startup(IConfiguration configuration)
  {
  Configuration = configuration;
  }
  public IConfiguration Configuration { get; }
  // This method gets called by the runtime. Use this method to add services to the container.
  public void ConfigureServices(IServiceCollection services)
  {
  // 禁用日志的控制台输出,防止由于线程同步造成的性能损失
  services.AddLogging(op => op.ClearProviders());
  services.AddMvc();
  }
  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
  app.UseRouting(routes => { routes.MapApplication(); });
  }
  }
  }
  以上三个项目都采用 Release 版本进行发布。
  dotnet publish -c Release
  ApiService01 部署在单独的 E3 1231 v3 16G DDR3 服务器。
  ApiService02 部署在单独的 i3-7100 16G DDR4 服务器。
  OcelotStudy 部署在单独的 E3 1231 v3 16G DDR3 服务器。
  三、开始测试
  这里我使用的是 WRK 来进行压力测试,OcelotStudy 网关项目的 IP 地址为 172.31.61.41:5000 ,故使用以下命令进行测试。
  ./wrk -t 10 -c 10000 -d 20s --latency --timeout 3s "http://172.31.61.41:5000/values"
  测试结果:
  我将 ApiService01 项目放在网关的服务器,直接调用 ApiService01 的接口,其压力测试情况。
  四、结语
  最后 Ocelot 的 QPS 结果为:3461.53
  直接请求 API 接口的 QPS 结果为:38874.50
  这样的结果让我感到很意外,不知道是由于 Ocelot 实现机制的原因,还是我的使用方法不对。这样的性能测试结果数据对于 API 网关来说确实不太好看,但也希望今后 Ocelot 能够继续努力。
  如果大家对于我的测试方式有疑问的话,可以在评论区指出,我将按照你所提供的方法再次进行测试。(PS: 我也不想换啊,多希望是我测错了)

      上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号