API网关选择:YARP还是Ocelot?

摘要

随着微服务架构的流行,API网关在系统架构中扮演着越来越重要的角色。在.NET生态中,YARP(Yet Another Reverse Proxy)和Ocelot是两种常用的API网关解决方案。那么,在实际应用中,我们该如何选择?本文将从易用性、文档、负载均衡、限流、身份验证、授权和性能等多个方面,对YARP和Ocelot进行详细对比,并附上具体的代码示例,帮助大家更好地理解和选择适合的API网关。

概述

YARP

YARP(Yet Another Reverse Proxy)是由微软维护的一个反向代理库,专为构建高度自定义的反向代理而设计。尽管它是一个较新的项目,但在GitHub上已经获得了超过8.7k的星标。YARP的优势在于其高性能、灵活的配置和丰富的文档支持。

GitHub地址:https://github.com/microsoft/reverse-proxy

Ocelot

Ocelot也是一个流行的API网关解决方案,已经存在了相当长的时间,积累了丰富的功能和社区支持。在GitHub上,Ocelot拥有超过8.4k的星标。尽管曾经有一段时间维护不积极,但近期又重新活跃起来。Ocelot提供了开箱即用的服务发现、请求聚合等功能。

GitHub地址:https://github.com/ThreeMammals/Ocelot

功能对比

负载均衡

两者都支持负载均衡,且配置方式相似。都可以通过配置多个下游服务,实现请求的负载均衡,并支持多种负载均衡策略,如轮询、随机等。

限流

YARP

YARP利用ASP.NET Core内置的限流中间件,提供了灵活的限流策略。支持固定窗口、滑动窗口、令牌桶、并发限制等多种算法。此外,YARP还支持自定义限流算法,满足特殊需求。

Ocelot

Ocelot也提供了限流功能,但在灵活性上略逊一筹。Ocelot的限流主要基于固定窗口,配置相对简单,但自定义能力有限。

身份验证与授权

YARP

YARP支持与ASP.NET Core的身份验证和授权机制集成。可以定义自定义的授权策略,支持基于声明、角色等多种方式的授权。配置灵活,能够满足复杂的安全需求。

Ocelot

Ocelot也支持身份验证和授权,但主要以基于声明的授权为主。相比之下,Ocelot的授权配置较为简单,灵活性不如YARP。

性能

在性能测试中,YARP显著优于Ocelot。在相同的测试条件下,YARP每秒处理的请求数比Ocelot高出约25%。对于高负载、高并发的应用场景,YARP的性能优势更加明显。

实践示例

接下来,我们通过具体的代码示例,展示如何使用YARP和Ocelot构建API网关,并实现负载均衡、限流等功能。

项目结构

我们使用基架自带的weatherforecastAPI。我们的目标是将该API置于API网关之后,使用YARP和Ocelot分别实现。

使用YARP构建API网关

1. 创建YARP网关项目

新建一个空的ASP.NET Core Web应用程序,命名为YarpGateway

2. 安装YARP包

YarpGateway项目中,安装YARP的NuGet包:

Install-Package Yarp.ReverseProxy

3. 配置Program.cs

Program.cs中,添加YARP所需的服务和中间件:

var builder = WebApplication.CreateBuilder(args);

// 添加YARP反向代理服务,并加载配置
builder.Services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); var app = builder.Build(); // 配置YARP中间件
app.MapReverseProxy(); app.Run();

4. 配置appsettings.json

appsettings.json中,添加ReverseProxy配置节:

{
"ReverseProxy": {
"Routes": {
"forecast-routes": {
"ClusterId": "forecastCluster",
"Match": {
"Path": "/forecast/{**catch-all}"
}
}
},
"Clusters": {
"forecastCluster": {
"Destinations": {
"destination1": {
"Address": "http://localhost:5001/"
},
"destination2": {
"Address": "http://localhost:5002/"
}
},
"LoadBalancingPolicy": "RoundRobin"
}
}
}
}

说明:

  • Routes:定义了请求匹配规则,将匹配到/forecast/*的请求路由到forecastCluster
  • Clusters:定义了下游服务的集合,这里配置了两个目标地址,用于负载均衡。
  • LoadBalancingPolicy:设置负载均衡策略为RoundRobin(轮询)。

5. 添加限流

在YARP中,可以利用ASP.NET Core的限流中间件进行配置。

首先,在Program.cs中添加限流服务:

builder.Services.AddRateLimiter(_ =>
{
_.AddFixedWindowLimiter("fixed", options =>
{
options.Window = TimeSpan.FromSeconds(10);
options.PermitLimit = 10;
options.QueueLimit = 0;
options.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst;
});
});

然后,在YARP的路由配置中,添加限流策略:

{
"ReverseProxy": {
"Routes": {
"forecast-routes": {
"ClusterId": "forecastCluster",
"Match": {
"Path": "/forecast/{**catch-all}"
},
"RateLimiterPolicy": "fixed"
}
},
// 其他配置
}
}

最后,在Program.cs中添加限流中间件:

app.UseRateLimiter();

6. 配置身份验证与授权

假设需要对/products路由进行授权,我们可以在YARP的路由配置中添加AuthorizationPolicy

{
"AuthorizationPolicy": "RequireAuthenticatedUser"
}

Program.cs中,添加身份验证和授权服务,这里以JWT Scheme为例:

builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://your-auth-server";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
}); builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireAuthenticatedUser", policy =>
{
policy.RequireAuthenticatedUser();
});
});

并添加中间件:

app.UseAuthentication();
app.UseAuthorization();

使用Ocelot构建API网关

1. 创建Ocelot网关项目

新建一个空的ASP.NET Core Web应用程序,命名为OcelotGateway

2. 安装Ocelot包

OcelotGateway项目中,安装Ocelot的NuGet包:

Install-Package Ocelot

3. 配置Program.cs

Program.cs中,添加Ocelot所需的服务和中间件:

var builder = WebApplication.CreateBuilder(args);

// 添加Ocelot服务
builder.Services.AddOcelot(); // 加载Ocelot配置文件
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true); var app = builder.Build(); // 配置Ocelot中间件,要加一个await还挺奇怪的
await app.UseOcelot(); app.Run();

4. 创建ocelot.json

在项目根目录下,添加ocelot.json配置文件:

{
"Routes": [
{
"DownstreamPathTemplate": "/forecast/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
},
{
"Host": "localhost",
"Port": 5002
}
],
"UpstreamPathTemplate": "/forecast/{everything}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:4000"
}
}

说明:

  • Routes:定义了请求的上游和下游路径模板,以及支持的HTTP方法。
  • DownstreamHostAndPorts:配置了下游服务的主机和端口,用于负载均衡。
  • LoadBalancerOptions:设置负载均衡策略为RoundRobin(轮询)。
  • GlobalConfiguration:全局配置,可以配置API网关的基本地址。

5. 添加限流

在Ocelot中,可以在路由配置中添加限流选项:

{
// 其他配置
"RateLimitOptions": {
"ClientWhitelist": [],
"EnableRateLimiting": true,
"Period": "10s",
"PeriodTimespan": 10,
"Limit": 10
}
}

6. 配置身份验证与授权

在Ocelot的配置中,添加身份验证和授权选项:

{
// 其他配置
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
},
"RouteClaimsRequirement": {
"role": "admin"
}
}

Program.cs中,添加身份验证和授权服务:

builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://your-auth-server";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
}); // Ocelot会自动使用ASP.NET Core的授权策略

测试配置

向YARP和Ocelot网关发送请求:

  • YARP网关

    GET http://localhost:3000/forecast/weatherforecast
  • Ocelot网关

    GET http://localhost:4000/forecast/weatherforecast

3. 验证负载均衡

多次发送请求,观察响应中服务器返回的实例信息,确认请求被轮询分配到不同的下游服务实例。

4. 验证限流

快速连续地发送超过限制次数的请求,观察是否返回相应的限流错误信息:

  • YARP:默认返回503 Service Unavailable

  • Ocelot:返回429 Too Many Requests,并包含错误信息。Ocelot的返回值更人性化

5. 验证身份验证与授权

使用dotnet签发本地测试JWT,尝试在不提供有效身份验证信息的情况下访问受保护的路由,验证是否被拒绝访问。

性能测试

为了对比YARP和Ocelot的性能,我们使用k6工具进行压力测试。三个项目都将运行在.NET9.0 Runtime、Release、Logging=Warning模式下

1. 设置测试脚本

创建yarp-test.jsocelot-test.js脚本,内容如下:

import http from 'k6/http';
import { check } from 'k6'; export const options = {
stages: [
{ duration: '10s', target: 20 },
{ duration: '50s', target: 20 }
]
}; export default function () {
const res = http.get('http://localhost:3000/forecast/weatherforecast');
check(res, {
'status was 200': (r) => r.status == 200,
});
}
import http from 'k6/http';
import { check } from 'k6'; export const options = {
stages: [
{ duration: '10s', target: 20 },
{ duration: '50s', target: 20 }
]
}; export default function () {
const res = http.get('http://localhost:4000/forecast/weatherforecast');
check(res, {
'status was 200': (r) => r.status == 200,
});
}

2. 运行性能测试

使用以下命令运行测试:

k6 run yarp-test.js
k6 run ocelot-test.js

3. 结果对比

根据测试结果,统计每秒处理的请求数(RPS):

  • YARP:约84120 RPS。
  • Ocelot:约57126 RPS。

YARP的性能明显优于Ocelot,快了47.3%,尤其是在高负载场景下。

结论

通过以上对比,我们可以发现:

  • YARP在性能、限流和授权的灵活性方面更具优势,适合需要高性能和高度自定义的应用场景,也更适合熟悉ASP.NET Core中间件的开发人员。
  • Ocelot提供了更丰富的功能,如服务发现、请求聚合等,开箱即用,适合快速构建和部署。

参考链接

[.NET] API网关选择:YARP还是Ocelot?的更多相关文章

  1. HTTP API网关选择之一Kong介绍

    为什么需要 API 网关 在微服务架构之下,服务被拆的非常零散,降低了耦合度的同时也给服务的统一管理增加了难度.如上图左所示,在旧的服务治理体系之下,鉴权,限流,日志,监控等通用功能需要在每个服务中单 ...

  2. .NET Core微服务之基于Ocelot实现API网关服务

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.啥是API网关? API 网关一般放到微服务的最前端,并且要让API 网关变成由应用所发起的每个请求的入口.这样就可以明显的简化客户端 ...

  3. Ocelot——初识基于.Net Core的API网关

    前言 前不久看到一篇<.NET Core 在腾讯财付通的企业级应用开发实践>,给现在研究.Net Core及想往微服务方向发展的人来了一剂强心针.于是我也就立刻去下Ocelot的源码及去阅 ...

  4. .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡

    大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...

  5. Ocelot实现API网关服务

    NET Core微服务之基于Ocelot实现API网关服务 https://www.cnblogs.com/edisonchou/p/api_gateway_ocelot_foundation_01. ...

  6. .Netcore 2.0 Ocelot Api网关教程(1)- 入门

    Ocelot(Github)Ocelot官方文档(英文)本文不会介绍Api网关是什么以及Ocelot能干什么需要对Api网关及Ocelot有一定的理论了解 开始使用Ocelot搭建一个入门级Api网关 ...

  7. .NET5 API 网关Ocelot+Consul服务注册

    1|0网关介绍 网关其实就是将我们写好的API全部放在一个统一的地址暴露在公网,提供访问的一个入口.在 .NET Core下可以使用Ocelot来帮助我们很方便的接入API 网关.与之类似的库还有Pr ...

  8. .NET Core开源API网关 – Ocelot中文文档

    Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由.请求聚合.服务发现.认证.鉴权.限流熔断.并内置了负载均衡器与Service Fabric.Butterfly ...

  9. .NET Core 玩一玩 Ocelot API网关

    .net 这几年国内确实不好过. 很多都选择转行.不过.net Core跨平台 开源之后 .社区的生态在慢慢建立.往好的趋势发展. 对于坚守在.NET战线的开发者来说 是个挺不错的消息.  特别是微软 ...

  10. .Netcore 2.0 Ocelot Api网关教程(6)- 配置管理

    本文介绍Ocelot中的配置管理,配置管理允许在Api网关运行时动态通过Http Api查看/修改当前配置.由于该功能权限很高,所以需要授权才能进行相关操作.有两种方式来认证,外部Identity S ...

随机推荐

  1. CTime类缺陷

    如果构造CTime的时间不在下面这个范围内,会抛出异常

  2. 分支定界方法(branch and cut,branch and price的基础)

    分支定界方法(branch and cut,branch and price的基础) 目录 1.基础版的分支定界算法(假设是min问题) 2.分支定界算法的步骤及其注意事项 2.1 具体的分支定界方法 ...

  3. 数据库系统原理——第三章 关系数据库标准语言SQL

    @ 目录 1.SQL的特点 2.SQL的组成 3SQL语句 3.1数据库的基本操作 3.2 基本表的定义.修改.删除 3.3索引的建立与删除 3.4数据更新 3.5数据查询 3.5.1单表查询 3.5 ...

  4. python处理大量数据excel表格中间格式神器pickle.pkl文件操作说明

    读取写入千万级别的excel文件费时费力,调试起来比较慢,面对这个问题,第一步可以先无脑全部转换成pkl文件,这样几乎和内存操作一样的速度. 例如: t=pd.read_excel("12月 ...

  5. Xor-FWT 的另一种理解方式

    Xor-FWT 的另一种理解方式 学习 \(\text{Fennec's Algorithm}\) 的额外收获,顺手记录一下. 假设我们要求两个长度为 \(n\) 的数组的异或卷积,为方便起见令 \( ...

  6. 利用 canvas 实现签名效果

    利用 canvas 实现签名效果 使用插件  jSignature  github:https://github.com/brinley/jSignature 如果再H5 中使用需要加载  flash ...

  7. 2.13 新手必读的Linux使用注意事项

    通过安装并体验 Linux 系统,读者应该能发现 Linux 与 Windows 的一些不同之处,本节就几个容易让初学者混淆的问题做重点讲解,以便加深读者对 Linux 系统的认识. Linux 严格 ...

  8. 2023NOIP A层联测31 T4 民主投票

    2023NOIP A层联测31 T4 民主投票 思维好题. 思路 首先可以设 \(s\) 每个人最多获得的票数,一开始所有点都把自己的票投给自己父亲. 如果一个点的票数超过 \(s\) 了,那么这个点 ...

  9. 做AI运动小程序有哪些解决方案,如何进行选型?

    引言:随着深度学习技术的发展进步,已经不再依赖强大的GPU算力,便可实现AI推理了,让AI技术渗透到了电脑.手机.智能设备等各类设备.体育.健身行业也不例外,阿里体育等IT大厂,推出的乐动力.天天跳绳 ...

  10. PTA题目集4~6的总结性Blog

    · 前言 本次的三个作业,由答题判题程序- 4.家居强电电路模拟程序- 1.家居强电电路模拟程序 -2组成. 答题判题程序-4是对前三次判题程序的最后升级,设计多个子类继承于基础题类来实现对每种题型的 ...