找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

6024

积分

0

好友

766

主题
发表于 2025-12-8 02:36:49 | 查看: 461| 回复: 0

第一章:引言与背景

1.1 微服务架构的兴起与 API 网关的重要性

在过去的十年中,软件架构经历了从单体应用向微服务架构的重大转变。微服务通过将复杂系统拆分为多个独立部署、松耦合的服务单元,显著提升了系统的可维护性、可扩展性和开发效率。

然而,微服务架构也带来了新的挑战:

  • 客户端需要与多个服务直接通信,增加了调用复杂度;
  • 跨服务的身份认证、限流、熔断、日志追踪等横切关注点难以统一管理;
  • 服务发现、负载均衡、协议转换等问题需集中处理。

为解决这些问题,API 网关(API Gateway)应运而生。API 网关作为系统的统一入口,承担了路由转发、安全控制、流量治理、协议适配等核心职责,成为微服务架构中不可或缺的组件。

1.2 Ocelot:.NET 生态中的经典网关

Github:ThreeMammals/Ocelot

在 .NET 生态中,Ocelot是早期最流行的开源 API 网关实现之一。它基于 ASP.NET Core 构建,支持请求路由与重写、身份验证与授权、限流、负载均衡、服务发现集成等功能。

Ocelot 因其配置简单、社区活跃、文档丰富,被广泛应用于中小型 .NET 微服务项目中。

然而,随着微服务规模扩大和性能要求提升,Ocelot 的局限性逐渐显现:

  • 性能瓶颈:基于中间件链式调用,高并发下延迟较高;
  • 功能扩展困难:插件机制不够灵活;
  • 维护活跃度下降:核心团队更新缓慢;
  • 缺乏对 HTTP/2、gRPC 等现代协议的原生支持。

1.3 YARP:微软官方推出的下一代反向代理网关

Github:dotnet/yarp

为应对上述挑战,微软于 2020 年正式推出YARP(Yet Another Reverse Proxy),并将其定位为“微软新一代网关”。YARP 并非传统意义上的完整 API 网关,而是一个高性能、可扩展、基于 .NET 的反向代理框架,开发者可在此基础上构建定制化网关。

YARP 的核心优势:

  1. 极致性能:YARP 直接基于 System.Net.Http 和 Kestrel 构建,绕过传统中间件管道,实现接近原生 HttpClient 的转发性能。官方基准测试显示,YARP 在吞吐量和延迟方面显著优于 Ocelot。
  2. 高度可定制:YARP 提供丰富的扩展点,允许开发者按需注入业务逻辑。
  3. 现代化协议支持:原生支持 HTTP/1.1、HTTP/2、WebSocket,未来计划支持 gRPC 代理。
  4. 微软官方维护:作为 .NET 基金会项目,YARP 获得微软持续投入,版本迭代稳定,安全性有保障。
  5. 与 .NET 生态无缝集成:支持依赖注入、配置系统、日志、指标等标准 .NET 功能,是现代.NET后端架构的优选组件。

1.4 为什么选择 YARP 替代 Ocelot?

对比维度 Ocelot YARP
性能 中等,中间件链式调用 高,直接底层网络操作
可扩展性 插件有限,需继承特定类 开放扩展点,任意中间件或自定义逻辑
协议支持 主要 HTTP/1.1 HTTP/1.1, HTTP/2, WebSocket
社区与维护 社区驱动,更新缓慢 微软官方维护,持续更新
学习曲线 简单,配置即用 需一定 .NET 底层知识
适用场景 中小型项目,快速搭建 中大型项目,高性能、高定制需求

结论:对于新项目或计划重构网关的现有系统,YARP 是更优选择。

1.5 本书目标与结构预览

本书旨在通过一个完整的电商微服务系统 Demo,教你如何使用 YARP 逐步构建高性能、可扩展的 API 网关。

项目 Demo 概述:

  • 前端:React SPA
  • 网关层:YARP
  • 微服务:用户服务、商品服务、订单服务、支付服务
  • 基础设施:Docker + Kubernetes、Consul、Redis、Prometheus + Grafana

第二章:YARP 核心原理与架构解析

2.1 YARP 是什么?——重新定义反向代理

YARP 是微软于 2020 年开源的高性能反向代理框架,其目标不是提供一个“开箱即用”的完整网关产品,而是为开发者提供一个可编程、可扩展、高性能的基础构建块,用于构建自定义的 API 网关、边缘服务或内部流量路由系统。

关键定位:YARP 是一个框架,而非产品。这意味着你需要编写少量代码来“激活”其能力,但换来的是极致的灵活性和性能。

YARP 的设计哲学源于微软内部大规模微服务系统的实践经验,同时完全基于 .NET 生态构建,天然支持云原生场景。

2.2 YARP 的整体架构

YARP 的架构清晰分层,主要由以下核心组件构成:

┌───────────────────────────────────────┐
│           HTTP 请求 (Ingress)         │
└──────────────────┬────────────────────┘
                   ▼
┌───────────────────────────────────────┐
│        ASP.NET Core 中间件管道        │
│  ┌─────────────┐    ┌─────────────┐   │
│  │ 自定义中间件 │ →  │ YARP 中间件 │   │
│  └─────────────┘    └──────┬──────┘   │
└────────────────────────────┼──────────┘
                             ▼
           ┌─────────────────────────────────┐
           │      路由匹配引擎 (Matcher)     │
           └────────────────┬────────────────┘
                            ▼
           ┌─────────────────────────────────┐
           │       目标集群选择 (Cluster)    │
           └────────────────┬────────────────┘
                            ▼
           ┌─────────────────────────────────┐
           │    请求转发器 (HttpProxy)       │
           │  (基于 HttpClient + Sockets)    │
           └────────────────┬────────────────┘
                            ▼
               ┌───────────────────────┐
               │ 后端服务 (Destination)│
               └───────────────────────┘

核心模块说明:

1. YARP 中间件(YarpMiddleware)

  • 注册在 ASP.NET Core 管道中;
  • 拦截所有进入的 HTTP 请求;
  • 触发路由匹配逻辑;
  • 若匹配成功,则交由 HttpProxy 执行转发。

2. 路由配置模型(Route & Cluster)

YARP 使用两层抽象:

  • Route(路由):定义如何匹配传入请求(如路径、方法、主机头等)。
  • Cluster(集群):定义一组后端目标(Destinations),包含负载均衡策略、健康检查、HTTP 客户端配置等。

3. HttpProxy(核心转发器)

  • 直接操作底层 SocketsHttpHandler,支持连接复用、HTTP/2 多路复用、流式传输;
  • 实现“零拷贝”转发以提升性能;
  • 支持请求/响应头修改、超时控制、重试机制等。

4. 可扩展点

YARP 提供多个接口供开发者注入自定义逻辑,如动态加载路由配置、修改请求/响应内容、自定义健康检查逻辑等。

2.3 YARP 的工作流程详解

当一个 HTTP 请求到达 YARP 网关时,其处理流程如下:

  1. 请求进入 ASP.NET Core 管道:由 Kestrel 接收,依次经过各类中间件。
  2. YARP 中间件拦截请求:获取当前生效的路由列表。
  3. 路由匹配:遍历所有 Route,按优先级或顺序进行匹配。
  4. 集群选择:根据匹配到的 Route 找到对应的 Cluster,执行负载均衡和健康检查。
  5. 请求转发:构造新的 HttpRequestMessage,应用转换规则,通过底层 HttpClient 发送到后端,并流式读取响应。
  6. 错误处理与重试:若后端失败,可配置重试策略。
  7. 日志与指标上报:自动记录代理延迟、状态码等,可集成分布式追踪。

2.4 YARP 与传统反向代理的对比

特性 Nginx Envoy YARP
语言 C C++ C# (.NET)
配置方式 静态配置文件 动态 xDS API JSON / Code / 动态 Provider
扩展性 Lua / C 模块 WASM / C++ Filter C# 接口 / DI / 中间件
性能 极高 高 高(接近 HttpClient 原生性能)
与 .NET 集成 弱 弱 极强

YARP 的独特价值:在 .NET 技术栈内,无需引入外部组件,即可实现高性能网关,且能深度集成业务逻辑。

2.5 本章小结

本章深入剖析了 YARP 的设计哲学、核心架构及其在 .NET 生态中的独特定位。我们明确了 YARP 是一个可编程的反向代理框架,其高性能来源于对底层网络栈的直接操作,通过 Route + Cluster 模型实现灵活路由,丰富的扩展点支持高度定制化需求。在 .NET 微服务场景中,YARP 是替代传统方案的理想选择。

第三章:从零搭建 YARP 网关项目

本章将带领你从空白项目开始,一步步构建一个可运行的 YARP 网关,并实现对后端微服务的代理转发。我们将采用 .NET 8 作为开发框架。

3.1 环境准备

开发环境要求

  • 操作系统:Windows / Linux / macOS
  • .NET SDK:.NET 8.0(LTS)
  • IDE:Visual Studio 2022 或 VS Code

创建解决方案结构

建议采用分层项目结构:

ECommerce.Gateway.Solution/
├── src/
│   ├── ECommerce.Gateway/          ← YARP 网关主项目
│   ├── ECommerce.UserService/      ← 用户微服务(Demo)
│   └── ECommerce.ProductService/   ← 商品微服务(Demo)
└── tests/

3.2 创建 YARP 网关项目

使用 CLI 创建项目

# 创建解决方案
dotnet new sln -n ECommerce.Gateway.Solution
# 创建网关项目
dotnet new webapi -n ECommerce.Gateway -o src/ECommerce.Gateway
# 添加到解决方案
dotnet sln add src/ECommerce.Gateway

安装 YARP NuGet 包

进入网关项目目录,执行:

dotnet add package Yarp.ReverseProxy

3.3 配置 YARP 基础代理功能

修改 Program.cs

打开Program.cs,替换为以下内容:

using Yarp.ReverseProxy;
var builder = WebApplication.CreateBuilder(args);
// 注册 YARP 服务
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
// 启用 YARP 中间件
app.MapReverseProxy();
app.Run();

配置 appsettings.json

在appsettings.json中添加ReverseProxy节点:

{
  "ReverseProxy": {
    "Routes": {
      "user_route": {
        "ClusterId": "user_cluster",
        "Match": { "Path": "/api/users/{**remainder}" }
      },
      "product_route": {
        "ClusterId": "product_cluster",
        "Match": { "Path": "/api/products/{**remainder}" }
      }
    },
    "Clusters": {
      "user_cluster": {
        "Destinations": { "user1": { "Address": "http://localhost:5001" } }
      },
      "product_cluster": {
        "Destinations": { "product1": { "Address": "http://localhost:5002" } }
      }
    }
  }
}

3.4 创建两个 Demo 微服务(用于测试)

用户服务(UserService)

dotnet new webapi -n ECommerce.UserService -o src/ECommerce.UserService
dotnet sln add src/ECommerce.UserService

修改其Program.cs,监听端口 5001,并定义简单 API 端点。

商品服务(ProductService)

dotnet new webapi -n ECommerce.ProductService -o src/ECommerce.ProductService
dotnet sln add src/ECommerce.ProductService

修改其Program.cs,监听端口 5002,并定义简单 API 端点。

3.5 启动与测试

同时启动三个项目

在三个独立的终端中分别运行三个项目。

发送测试请求

使用 curl 测试网关路由:

# 测试用户服务
curl http://localhost:5000/api/users
# 响应: Hello from User Service!
# 测试商品服务
curl http://localhost:5000/api/products
# 响应: Hello from Product Service!

如果看到上述响应,说明 YARP 网关已成功代理请求。

3.6 关键机制解析

路径重写行为

YARP 默认保留原始路径转发。例如,请求 /api/users/123 会转发到 http://localhost:5001/api/users/123。若需重写路径,可通过 Transforms 实现。

请求头透传

YARP 自动透传大部分请求头,但会添加标准代理头(如 X-Forwarded-For),后端服务可据此获取客户端真实 IP。

错误处理

  • 若后端服务未启动,YARP 返回 502 Bad Gateway。
  • 若路由不匹配,请求会继续执行后续中间件管道。

3.7 本章小结

本章完成了基于 .NET 8 的 YARP 网关项目创建、静态路由配置,并搭建了测试微服务验证了请求代理功能。你现在拥有了一个可工作的 YARP 网关原型,为后续集成高级功能打下基础。

第四章:路由配置详解——静态路由 vs 动态路由

在 YARP 中,路由是决定请求如何被处理的核心规则。本章将深入讲解 YARP 路由系统的各种匹配机制、配置方式及其适用场景。

4.1 路由的基本结构

YARP 的路由由 Match 条件和 Action 行为两部分组成。在配置中,一个典型路由如下:

"route_id": {
  "ClusterId": "backend_cluster",
  "Match": {
    "Path": "/api/{**catchall}",
    "Methods": [ "GET", "POST" ],
    "Hosts": [ "api.example.com" ]
  }
}

4.2 静态路由配置详解

静态路由指在应用启动时从配置文件加载,运行期间不可变的路由规则。

路径匹配模式

  1. 精确匹配:"Path": "/health"
  2. 参数占位符:"Path": "/api/users/{id}"
  3. 通配符捕获:"Path": "/api/{**remainder}" (必须放在路径末尾)

多条件组合匹配

YARP 支持 AND 逻辑组合多个匹配条件,如同时匹配路径、HTTP 方法、主机头和自定义请求头。

路由优先级控制

当多个路由可能匹配同一请求时,可通过显式设置 Order 字段(数值越小越优先)或依赖配置文件中的声明顺序来决定优先级。

4.3 高级静态匹配:Header 与 Query 匹配

可以配置路由根据特定的请求头(Header)或查询参数(Query Parameter)进行匹配,适用于灰度发布等场景。

4.4 动态路由配置:为什么需要它?

当微服务实例动态扩缩容、需要实时调整路由规则或与服务注册中心集成时,静态配置存在局限,此时动态路由配置成为必需。

4.5 实现动态路由:自定义 IProxyConfigProvider

YARP 通过 IProxyConfigProvider 接口支持动态配置加载。

创建动态配置提供者

创建一个实现 IProxyConfigProvider 接口的类,用于从内存、数据库或 API 加载路由和集群配置。该类需要提供一个 ChangeToken,以便在配置变更时通知 YARP 热更新。

注册动态提供者

在 Program.cs 中注册自定义的 IProxyConfigProvider,并确保 YARP 使用它来获取配置。

添加管理 API

可以暴露一个 API 端点,用于测试动态添加路由,无需重启网关即可生效。

4.6 与服务发现集成

在实际生产中,动态路由通常与 Consul、Kubernetes 等服务发现工具集成,自动根据服务实例的变化更新路由配置。

4.7 静态 vs 动态路由对比总结

维度 静态路由 动态路由
配置来源 appsettings.json 代码 / 数据库 / 服务注册中心
更新方式 重启应用 热更新(无需重启)
适用规模 小型、稳定系统 中大型、弹性系统
开发复杂度 低 中高

最佳实践:初期使用静态路由快速验证,上线前切换为动态路由以支持弹性伸缩。

4.8 本章小结

本章全面解析了 YARP 路由系统的配置能力,包括静态路由的多维匹配、动态路由的实现原理,为后续与服务发现集成打下基础。

第五章:身份认证与授权集成

在微服务架构中,统一身份认证与授权是 API 网关的核心职责之一。本章将教你如何在 YARP 网关中集成 JWT Bearer Token 验证。

5.1 认证模型设计:网关 vs 微服务

两种常见模式

  1. 网关认证 + 透传 Token:网关验证 JWT 合法性,验证通过后将原始 Token 转发给后端。(推荐)
  2. 网关认证 + 剥离 Token:网关验证后生成内部凭证,后端无需处理 JWT。

YARP 推荐采用第一种模式:网关负责“认证”,微服务负责“授权”。

5.2 在 YARP 中集成 JWT Bearer 认证

YARP 本身不包含认证逻辑,但可无缝集成 ASP.NET Core 的标准认证中间件。

添加认证服务

在 Program.cs 中添加 JWT Bearer 认证服务,配置颁发者(Authority)、受众(Audience)等验证参数。

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.Authority = "https://localhost:5005";
        options.Audience = "ecommerce_api";
    });

并在 HTTP 请求管道中启用认证与授权中间件,顺序必须在 MapReverseProxy() 之前。

配置受保护路由

可以为特定路由配置授权策略(AuthorizationPolicy),要求请求必须经过认证。未配置策略的路由则允许公开访问。

5.3 搭建本地身份提供商(用于测试)

可以快速搭建一个简易的 IdentityServer4 或 OpenIddict 项目,用于颁发测试用的 JWT Token。配置包括定义 API 作用域、客户端和测试用户。

5.4 获取测试 Token 并调用网关

使用工具向身份提供商请求 Token,然后在调用受保护的网关接口时,在 Authorization 头中携带该 Token。网关会验证 Token 的有效性。

5.5 高级场景:Claims 转换与头注入

通过 YARP 的 Transforms 功能,可以在转发请求前,将认证用户的信息(如用户ID、角色)从 JWT Claims 中提取出来,并注入到新的请求头(如 X-User-ID)中传递给后端微服务。这有助于实现安全的上下文传递,避免后端重复解析 Token。

5.6 本章小结

本章完成了在 YARP 网关中集成 JWT 认证、按路由策略控制访问权限,并通过 Transforms 将用户信息注入请求头。你现在拥有了一个具备统一认证能力的安全网关。

第六章:限流与熔断策略实现

在高并发微服务系统中,流量治理是保障系统稳定性的关键手段。YARP 可轻松集成 .NET 生态中的成熟组件实现限流与熔断。

6.1 限流策略设计

为什么需要限流?

防止恶意攻击、保护后端服务不被突发流量压垮、实现多租户配额管理等。

限流维度

包括全局限流、路由限流、客户端限流(按 IP 或 API Key)、用户限流(按用户 ID)。推荐组合使用。

6.2 集成 AspNetCoreRateLimit 实现限流

安装与配置

安装 AspNetCoreRateLimit NuGet 包,并在 Program.cs 中注册所需服务(内存缓存、配置选项等)。在 HTTP 管道中尽早启用限流中间件。

配置限流规则

在 appsettings.json 中配置 IP 或客户端限流规则,可以针对特定端点(路由)设置时间段内的请求次数限制。超出限制的请求将返回 429 状态码。

6.3 基于 YARP Transforms 的自定义限流

对于需要结合 JWT Claims 等业务属性的更灵活限流逻辑,可以利用 YARP 的 Request Transform,在转发前执行自定义的限流判断,并通过设置 SuppressProxyPipeline 来阻止转发。

6.4 熔断策略:防止雪崩效应

什么是熔断?

熔断器模式包含三种状态:关闭(正常)、打开(快速失败)、半开(尝试恢复)。当后端服务失败率达到阈值时触发熔断,避免资源耗尽。

集成 Polly 实现熔断

安装 Polly 包。通过 YARP 的 ConfigureHttpClient 方法,为每个集群的 HttpClient 配置 Polly 的熔断策略,例如在连续出现5次失败后熔断30秒。

6.5 限流与熔断的监控与告警

配置限流库和熔断策略的日志记录,并在状态变更时(如触发熔断)上报指标或触发告警,这对于运维至关重要。

6.6 本章小结

本章实现了 YARP 网关的限流与熔断两大核心稳定性机制。你的网关现在不仅能转发请求,还具备了自我保护能力,确保核心服务在高负载或下游异常时的可用性。




上一篇:Qt QDateTime完全指南:日期时间与字符串、毫秒、时间戳转换实战
下一篇:Rust项目编译提速实战:三行配置将22分钟降至38秒
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-9-28 16:58 , Processed in 1.208954 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表