Ocelot API 网关
一、API 网关基础
1. 什么是 API 网关?
API 网关是微服务架构中的统一入口,所有客户端请求都通过网关路由到后端服务。
解决的问题:
- ✅ 统一入口 - 客户端只需知道网关地址
- ✅ 安全 - 统一认证授权,服务不直接暴露
- ✅ 解耦 - 客户端不需要知道后端服务地址
- ✅ 功能集中 - 限流、熔断、日志等功能统一实现
- ✅ 协议转换 - HTTP 转 gRPC 等
2. Ocelot 是什么?
Ocelot 是一个基于 .NET Core 的 API 网关,专为微服务架构设计。
核心功能:
- ✅ 路由转发
- ✅ 负载均衡
- ✅ 认证授权
- ✅ 限流
- ✅ 熔断
- ✅ 请求聚合
- ✅ 服务发现集成
二、快速开始
1. 安装和配置
安装 NuGet 包:
bash
dotnet add package Ocelot创建 ocelot.json 配置文件:
json
{
"Routes": [
{
"DownstreamPathTemplate": "/api/users/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/users/{everything}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
"Key": "UserService"
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5000"
}
}Program.cs 配置:
csharp
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
var builder = WebApplication.CreateBuilder(args);
// 添加 Ocelot 配置
builder.Configuration
.SetBasePath(builder.Environment.ContentRootPath)
.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
// 注册 Ocelot 服务
builder.Services.AddOcelot(builder.Configuration);
var app = builder.Build();
// 使用 Ocelot 中间件
await app.UseOcelot();
app.Run();三、路由配置详解
1. 基本路由配置
json
{
"Routes": [
{
"DownstreamPathTemplate": "/api/users/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/users/{everything}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
"Key": "UserService"
}
]
}配置说明:
DownstreamPathTemplate- 后端服务的实际路径DownstreamScheme- 后端协议(http/https)DownstreamHostAndPorts- 后端服务地址和端口UpstreamPathTemplate- 客户端访问网关的路径UpstreamHttpMethod- 允许的 HTTP 方法Key- 路由唯一标识
2. 路径参数
json
{
"UpstreamPathTemplate": "/users/{userId}",
"DownstreamPathTemplate": "/api/users/{userId}"
}支持的占位符:
{everything}- 匹配所有路径{userId}- 匹配路径参数{id}- 匹配路径参数
3. 查询字符串
json
{
"UpstreamPathTemplate": "/users?page={page}&size={size}",
"DownstreamPathTemplate": "/api/users?page={page}&size={size}"
}四、负载均衡
1. 负载均衡类型
json
{
"DownstreamHostAndPorts": [
{ "Host": "localhost", "Port": 5001 },
{ "Host": "localhost", "Port": 5002 },
{ "Host": "localhost", "Port": 5003 }
],
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}负载均衡策略:
RoundRobin- 轮询(默认)LeastConnection- 最少连接NoLoadBalance- 无负载均衡(使用第一个)
2. 自定义负载均衡
csharp
// 实现自定义负载均衡器
public class CustomLoadBalancer : ILoadBalancer
{
public async Task<Response<ServiceHostAndPort>> Lease(
HttpClient httpClient,
DownstreamRoute downstreamRoute,
ServiceDiscoveryProvider serviceDiscoveryProvider)
{
// 自定义负载均衡逻辑
return new OkResponse<ServiceHostAndPort>(hostAndPort);
}
public void Release(ServiceHostAndPort hostAndPort) { }
}
// 注册
builder.Services.AddOcelot()
.AddSingletonDefinedAggregator<CustomLoadBalancer>();五、认证和授权
1. JWT 认证
配置认证:
csharp
// Program.cs
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
builder.Services.AddOcelot(builder.Configuration);路由配置:
json
{
"Routes": [
{
"UpstreamPathTemplate": "/users/{everything}",
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
}
]
}2. IdentityServer 集成
json
{
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": [ "api1" ]
}
}3. 基于角色的授权
json
{
"RouteClaimsRequirement": {
"role": "admin"
}
}六、限流(Rate Limiting)
1. 基本限流配置
json
{
"RateLimitOptions": {
"EnableRateLimiting": true,
"Period": "1m",
"PeriodTimespan": 60,
"Limit": 100
}
}配置说明:
EnableRateLimiting- 是否启用限流Period- 时间周期(1m、1h 等)PeriodTimespan- 时间周期(秒)Limit- 允许的请求数
2. 客户端白名单
json
{
"RateLimitOptions": {
"ClientWhitelist": [ "admin-client" ],
"EnableRateLimiting": true,
"Period": "1m",
"Limit": 1000
}
}3. 自定义限流
csharp
// 安装包
dotnet add package Ocelot.RateLimit
// 配置
builder.Services.AddOcelot(builder.Configuration)
.AddRateLimit();七、熔断(Circuit Breaker)
1. QoS 配置
json
{
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000
}
}配置说明:
ExceptionsAllowedBeforeBreaking- 允许的异常次数DurationOfBreak- 熔断持续时间(秒)TimeoutValue- 请求超时时间(毫秒)
2. Polly 集成
csharp
// 安装包
dotnet add package Ocelot.Provider.Polly
// 配置
builder.Services.AddOcelot(builder.Configuration)
.AddPolly();高级配置:
json
{
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10,
"TimeoutValue": 5000,
"MaxRetries": 3
}
}八、服务发现
1. Consul 集成
安装包:
bash
dotnet add package Ocelot.Provider.Consul配置:
csharp
builder.Services.AddOcelot(builder.Configuration)
.AddConsul();ocelot.json 配置:
json
{
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
}
},
"Routes": [
{
"DownstreamPathTemplate": "/api/users/{everything}",
"UpstreamPathTemplate": "/users/{everything}",
"ServiceName": "UserService",
"UseServiceDiscovery": true
}
]
}2. Eureka 集成
bash
dotnet add package Ocelot.Provider.Eurekacsharp
builder.Services.AddOcelot(builder.Configuration)
.AddEureka();九、请求聚合
1. 配置聚合
json
{
"Routes": [
{
"Key": "UserService",
"UpstreamPathTemplate": "/users/{everything}"
},
{
"Key": "OrderService",
"UpstreamPathTemplate": "/orders/{everything}"
}
],
"Aggregates": [
{
"RouteKeys": [ "UserService", "OrderService" ],
"UpstreamPathTemplate": "/summary/{userId}",
"UpstreamHttpMethod": [ "GET" ]
}
]
}2. 自定义聚合器
csharp
public class CustomAggregator : IDefinedAggregator
{
public async Task<DownstreamResponse> Aggregate(
List<DownstreamResponse> responses)
{
var user = await responses[0].Content.ReadAsStringAsync();
var orders = await responses[1].Content.ReadAsStringAsync();
var summary = new
{
User = JsonSerializer.Deserialize<User>(user),
Orders = JsonSerializer.Deserialize<List<Order>>(orders)
};
var json = JsonSerializer.Serialize(summary);
var content = new StringContent(json);
return new DownstreamResponse(content, HttpStatusCode.OK,
responses.SelectMany(r => r.Headers), "OK");
}
}
// 注册
builder.Services.AddOcelot()
.AddSingletonDefinedAggregator<CustomAggregator>();十、请求/响应转换
1. 请求头转换
json
{
"AddHeadersToDownstream": {
"X-Custom-Header": "value"
},
"AddHeadersToUpstream": {
"X-Response-Header": "value"
}
}2. 查询字符串转换
json
{
"AddQueriesToDownstream": {
"api-version": "1.0"
}
}3. 请求体转换
csharp
// 自定义中间件
public class RequestTransformMiddleware : OcelotMiddleware
{
public async Task InvokeAsync(DownstreamContext context)
{
// 转换请求体
var requestBody = await context.DownstreamRequest.Content.ReadAsStringAsync();
var transformed = TransformRequestBody(requestBody);
context.DownstreamRequest.Content = new StringContent(transformed);
await Next.Invoke(context);
}
}十一、缓存
1. 响应缓存
json
{
"FileCacheOptions": {
"TtlSeconds": 60,
"Region": "users"
}
}2. 自定义缓存
csharp
// 安装包
dotnet add package Ocelot.Cache.CacheManager
// 配置
builder.Services.AddOcelot(builder.Configuration)
.AddCacheManager(x => x.WithDictionaryHandle());十二、监控和日志
1. 请求日志
csharp
// 添加日志
builder.Services.AddLogging(builder =>
{
builder.AddConsole();
builder.AddDebug();
});2. 性能监控
csharp
// 添加 Application Insights
builder.Services.AddApplicationInsightsTelemetry();
// Ocelot 会自动记录请求指标3. 健康检查
csharp
builder.Services.AddHealthChecks();
builder.Services.AddOcelot(builder.Configuration);
app.MapHealthChecks("/health");十三、常见面试题
Q1: Ocelot 和 Nginx 的区别?
| 特性 | Ocelot | Nginx |
|---|---|---|
| 语言 | .NET Core | C |
| 配置 | JSON 文件 | 配置文件 |
| 功能 | 网关功能丰富 | 反向代理、负载均衡 |
| 集成 | 与 .NET 生态集成好 | 通用 |
| 性能 | 较高 | 非常高 |
| 适用场景 | .NET 微服务 | 通用网关 |
Q2: 如何实现动态路由?
方案一:配置中心
csharp
// 从 Consul KV 读取配置
builder.Configuration.AddConsul("ocelot.json", options =>
{
options.ReloadOnChange = true;
});方案二:数据库
csharp
// 从数据库读取路由配置
public class DatabaseConfigurationProvider : IConfigurationProvider
{
public async Task<IOcelotConfiguration> Get()
{
var routes = await _dbContext.Routes.ToListAsync();
return BuildConfiguration(routes);
}
}Q3: 如何处理跨域(CORS)?
csharp
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
app.UseCors("AllowAll");Q4: 如何实现灰度发布?
json
{
"Routes": [
{
"Key": "UserService",
"DownstreamHostAndPorts": [
{ "Host": "v1.service.com", "Port": 80 },
{ "Host": "v2.service.com", "Port": 80 }
],
"LoadBalancerOptions": {
"Type": "Custom",
"Key": "GrayRelease"
}
}
]
}Q5: 如何实现 API 版本控制?
json
{
"Routes": [
{
"UpstreamPathTemplate": "/v1/users/{everything}",
"DownstreamPathTemplate": "/api/v1/users/{everything}"
},
{
"UpstreamPathTemplate": "/v2/users/{everything}",
"DownstreamPathTemplate": "/api/v2/users/{everything}"
}
]
}十四、最佳实践
- ✅ 使用服务发现 - 动态获取服务地址
- ✅ 启用限流 - 保护后端服务
- ✅ 配置熔断 - 防止级联故障
- ✅ 统一认证 - 在网关层处理认证
- ✅ 监控和日志 - 记录所有请求
- ✅ 健康检查 - 监控网关状态
- ✅ 配置热重载 - 支持动态配置更新
- ✅ 使用 HTTPS - 生产环境必须
- ❌ 不要过度聚合 - 影响性能
- ❌ 不要忽略超时配置 - 防止请求堆积