[.NET] API网关选择:YARP还是Ocelot?
[.NET] API网关选择:YARP还是Ocelot?
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高出约50%。对于高负载、高并发的应用场景,YARP的性能优势更加明显。
实践示例
接下来,我们通过具体的代码示例,展示如何使用YARP和Ocelot构建API网关,并实现负载均衡、限流等功能。
项目结构
我们使用基架自带的weatherforecast
API。我们的目标是将该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.js
和ocelot-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提供了更丰富的功能,如服务发现、请求聚合等,开箱即用,适合快速构建和部署。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
2024-01-07 yarnadd指定版本的使用方法
2022-01-07 React Suite 5.4.4 版本更新,React UI 库
2020-01-07 浏览器报Mixed Content错误的解决
2019-01-07 必须要学会webpack打包,并到特别精通的程度
2019-01-07 vue中过滤器filters的使用