当前位置: 首页 > news >正文

ABP VNext + Ocelot API 网关:微服务统一入口与安全策略

🚀 ABP VNext + Ocelot API 网关:微服务统一入口与安全策略 🛡️


📚 目录

    • 🚀 ABP VNext + Ocelot API 网关:微服务统一入口与安全策略 🛡️
    • 一、引言 📝
    • 二、环境与依赖 📦
    • 三、系统架构概览 🔍
      • 🤖 核心组件
    • 四、安装与初始配置 ⚙️
      • Program.cs 完整示例
    • 五、基础路由与聚合 🔄
    • 六、负载均衡策略 ⚖️
    • 七、JWT 鉴权与转发 🔑
    • 八、限流、熔断与降级 🚦
    • 九、动态路由热加载 🔄
    • 🔀 Merge Request 🤖 流程图
    • 十、服务发现与健康检查 📡
    • 十一、可观测性与监控 📈
    • 十二、Swagger/OpenAPI 聚合 🖼️
    • 附录 📎
      • 参考链接 🔗


一、引言 📝

TL;DR

  • 🌐 利用 Ocelot 为 ABP VNext 微服务群组构建统一网关入口
  • 🔄 支持路由聚合、负载均衡、JWT 鉴权、IP/速率限流、熔断与降级
  • 🔄 动态路由热加载,多环境差异化配置(本地文件、环境变量、Consul/Etcd KV)
  • 🔍 集成 Consul/Etcd 服务发现和健康检查,接入 OpenTelemetry + Prometheus + Jaeger 可观测性

📚 背景与动机
在微服务架构下,客户端直连各服务带来跨域、鉴权分散、接口爆炸、性能瓶颈等挑战。API 网关 🌉 统一入口后,可集中处理路由、鉴权、限流、熔断、聚合及监控,简化客户端并提升系统安全与可维护性。

💡 选型对比

特性Kubernetes IngressOcelot 网关
语言实现NGiNX/Envoy 等 C/C++.NET
路由聚合❌ 无原生支持✅ 原生 Aggregates
鉴权限流需额外插件自带 JWT、限流、QoS、Fallback 支持
热加载重启或重部署 IngressController✅ 支持本地文件、环境变量、Consul/Etcd KV 热更新

二、环境与依赖 📦

运行平台:.NET 6.0 + ,ABP VNext 6.x +
NuGet 包

# Ocelot 核心
dotnet add package Ocelot
# Consul 与动态配置
dotnet add package Ocelot.Provider.Consul
dotnet add package Winton.Extensions.Configuration.Consul
dotnet add package Consul       
# Etcd 可选
dotnet add package Etcd.Client  
# 限流
dotnet add package AspNetCoreRateLimit
# Swagger 聚合
dotnet add package SwaggerForOcelot

项目结构

/ApiGateway├─ appsettings.json├─ ocelot.json├─ ocelot.Development.json├─ ocelot.Production.json└─ Program.cs

三、系统架构概览 🔍

🏗️ 请求流程图 (Mermaid)

HTTP
ServiceDiscovery
gRPC/HTTP
gRPC/HTTP
gRPC/HTTP
客户端
Ocelot API 网关
Consul/Etcd
OrderService
UserService
ProductService

🤖 核心组件

  • Ocelot 网关:统一入口、路由聚合、鉴权限流、限流、熔断降级、监控
  • Consul/Etcd:服务注册/发现、健康检查、KV 存储
  • ABP 微服务:业务实现及 /health 健康端点
  • 监控链路:OpenTelemetry → Prometheus → Grafana;Trace → Jaeger/Zipkin

四、安装与初始配置 ⚙️

# 创建项目
dotnet new webapi -n ApiGateway
cd ApiGateway
# 引入依赖
# Ocelot 核心
dotnet add package Ocelot
# 动态配置与 Consul
dotnet add package Ocelot.Provider.Consul
dotnet add package Winton.Extensions.Configuration.Consul
dotnet add package Consul
# 限流
dotnet add package AspNetCoreRateLimit
# Swagger 聚合
dotnet add package SwaggerForOcelot

Program.cs 完整示例

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using AspNetCoreRateLimit;
using Winton.Extensions.Configuration.Consul;var builder = WebApplication.CreateBuilder(args);
var env = builder.Environment;// ============ 配置文件加载 ============
builder.Configuration.AddJsonFile("appsettings.json", false, true).AddJsonFile("ocelot.json", false, true).AddJsonFile($"ocelot.{env.EnvironmentName}.json", true, true).AddEnvironmentVariables(prefix: "Ocelot__").AddConsul("ocelot.json", opts => {opts.ConsulConfigurationOptions = c => c.Address = new Uri(builder.Configuration["Consul:Host"]);opts.Optional = true; opts.ReloadOnChange = true;});// ============ 服务注册 ============
builder.Services.AddHealthChecks();// CORS
builder.Services.AddCors(opts =>opts.AddPolicy("GatewayCors", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())
);// Forwarded Headers
builder.Services.Configure<ForwardedHeadersOptions>(opts => {opts.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});// Authentication & Authorization
builder.Services.AddAuthentication().AddJwtBearer("GatewayAuth", o => {o.Authority = builder.Configuration["AuthServer:Authority"];o.Audience = "gateway_api";o.RequireHttpsMetadata = true;});
builder.Services.AddAuthorization();// Rate Limiting
builder.Services.AddOptions();
builder.Services.AddMemoryCache();
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("RateLimitOptions"));
builder.Services.AddInMemoryRateLimiting();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();// HttpClientFactory + DelegatingHandler 🔑
builder.Services.AddTransient<JwtTokenDelegatingHandler>();
builder.Services.AddHttpClient("OcelotClient").AddHttpMessageHandler<JwtTokenDelegatingHandler>();// Swagger 聚合
builder.Services.AddSwaggerForOcelot(builder.Configuration);// Ocelot + Consul + DelegatingHandler 🔧
builder.Services.AddOcelot(builder.Configuration).AddConsul().AddConfigStoredInConsul().AddDelegatingHandler<JwtTokenDelegatingHandler>(true);var app = builder.Build();// ============ 中间件管道 ============
app.UseForwardedHeaders();
app.UseCors("GatewayCors");
app.UseAuthentication();
app.UseAuthorization();
app.UseHealthChecks("/health");// SwaggerForOcelot UI
app.UseSwaggerForOcelotUI(opt => opt.PathToSwaggerGenerator = "/swagger/docs");app.MapGet("/", () => "🚀 API Gateway is running 🚀");await app.UseOcelot();
app.Run();

💡 Tips

  1. AddEnvironmentVariables(prefix: "Ocelot__") 可通过环境变量覆盖任意 ocelot.json 节点。
  2. 确保在 UseOcelot() 之前调用 UseForwardedHeaders()UseAuthentication()UseAuthorization()

五、基础路由与聚合 🔄

📄 ocelot.json 示例

{"Routes": [{"Key": "orders","DownstreamPathTemplate": "/api/orders/{everything}","DownstreamScheme": "https","DownstreamHostAndPorts": [{ "Host": "orderservice", "Port": 443 }],"UpstreamPathTemplate": "/gateway/orders/{everything}","UpstreamHttpMethod": ["GET","POST"]},{"Key": "users","DownstreamPathTemplate": "/api/users/{everything}","UpstreamPathTemplate": "/gateway/users/{everything}","UpstreamHttpMethod": ["GET","POST"]}],"Aggregates": [{"RouteKeys": ["orders","users"],"UpstreamPathTemplate": "/gateway/dashboard","UpstreamHttpMethod": ["GET"]}]
}

⚠️ Pitfall:聚合顺序由 RouteKeys 决定,避免互依。


六、负载均衡策略 ⚖️

"LoadBalancerOptions": { "Type": "RoundRobin" }

🎯 算法:RoundRobin、LeastConnection、NoLoadBalancer。

💡 Tips:在 Kubernetes 环境下,优先使用 K8s Service 做 LB,Ocelot 仅做路由。


七、JWT 鉴权与转发 🔑

public class JwtTokenDelegatingHandler : DelegatingHandler
{protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage req, CancellationToken ct){var token = req.Headers.Authorization?.Parameter;if (!string.IsNullOrEmpty(token))req.Headers.Add("Authorization", $"Bearer {token}");return await base.SendAsync(req, ct);}
}

八、限流、熔断与降级 🚦

📄 appsettings.json

"RateLimitOptions": {"EnableEndpointRateLimiting": true,"ClientWhitelist": ["127.0.0.1"],"GeneralRules": [{ "Endpoint": "*://*/gateway/*", "Period": "1s", "Limit": 5 }]
}

📄 ocelot.json

"Routes": [{"Key": "products",// ..."QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, "DurationOfBreak": 10000 },"Fallback": {"DownstreamFallbackPath": "/api/fallback/products","DownstreamFallbackHttpMethod": ["GET"],"IsInline": false}}
]

💡 Tips:熔断后自动路由到 Fallback 接口,可返回静态数据或降级提示。


九、动态路由热加载 🔄

Consul KV:

consul kv put ocelot.json @ocelot.json

无需重启,Ocelot 自动热加载。


🔀 Merge Request 🤖 流程图

Commit & Push
Open MR
Code Review
Approve/Request Changes
Merge
CI/CD
Smoke Test
Developer
Feature Branch
GitLab/GitHub
Reviewer
Main Branch
Deployment
Prod
Done

十、服务发现与健康检查 📡

builder.Services.AddSingleton<IConsulClient>(sp =>new ConsulClient(cfg => { cfg.Address = new Uri(builder.Configuration["Consul:Host"]); })
);
// .AddOcelot() 中已 AddConsul()

❤️‍🩹 健康检查:微服务暴露 /health,Consul 定期探测,剔除异常实例。


十一、可观测性与监控 📈

1️⃣ Metrics (Prometheus)

app.UseOcelot().UseMetricServer();

2️⃣ Trace (OpenTelemetry + Jaeger)

builder.Services.AddOpenTelemetryTracing(tp =>tp.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddJaegerExporter(opts => opts.AgentHost = builder.Configuration["Jaeger:Host"])
);

📝 日志:Serilog + RequestLogging 中间件,输出 RequestIdLatencyStatusCode


十二、Swagger/OpenAPI 聚合 🖼️

builder.Services.AddSwaggerForOcelot(builder.Configuration);
app.UseSwaggerForOcelotUI(opt => opt.PathToSwaggerGenerator = "/swagger/docs");

附录 📎

参考链接 🔗

  • Ocelot 官方文档
  • ABP VNext 微服务指南
  • prometheus-net
  • OpenTelemetry .NET
http://www.lryc.cn/news/575196.html

相关文章:

  • Boosting:从理论到实践——集成学习中的偏差征服者
  • webman 利用tcp 做服务端 对接物联网
  • 机器学习×第十五卷:集成学习下篇——她开始构建每一轮更接近你的贴靠路径(XGBoost)
  • 基于STM32的个人健康助手的设计
  • Containerd 容器技术
  • 基于Hp感染的慢性胃炎居家管理小程序的设计与实现(消息震动)
  • LVS-DR负载均衡群集深度实践:高性能架构设计与排障指南
  • 鸿蒙OpenHarmony[Disassembler反汇编工具]ArkTS运编译工具链
  • vue3递归组件的使用
  • LVS-NAT负载均衡群集实战:原理、部署与问题排查
  • Vue计算属性与监视属性
  • 机器人 “离线觉醒” ? 摆脱人类“控制”!Google DeepMind 优化 AI 让机器人断网不断智!
  • spring项目启动sheel脚本
  • 如何打造Apache Top-Level开源时序数据库IoTDB
  • 北斗导航 | 基于CNN-LSTM-PSO算法的接收机自主完好性监测算法
  • 服务器开放端口如何设置,本地内网开通应用端口让外网访问连接步骤
  • Fisco Bcos学习 - 控制台搭建和基本使用
  • 在ASP.NET Core WebApi中使用标识框架(Identity)
  • 网络安全漏洞扫描是什么?如何识别目标进行扫描?
  • 通用 Excel 导出功能设计与实现:动态列选择与灵活配置
  • 国道观察者手记
  • React + Umi(Umijs/Max) 搭建项目及配置
  • 大学专业科普 | 物联网、自动化和人工智能
  • 多服务器IP白名单配置(使用redis stream实现)
  • 神经网络的运作方式类比讲解
  • 【EI会议征稿】东北大学主办第三届机器视觉、图像处理与影像技术国际会议(MVIPIT 2025)
  • Arm架构下麒麟V10桌面版安装MySQL
  • Android14音频子系统-Linux音频子系统ASoC-ALSA
  • Linux size命令详解
  • Android14音频子系统-Linux音频子系统ALSA