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

354

积分

0

好友

48

主题
发表于 21 小时前 | 查看: 3| 回复: 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.HttpKestrel 构建,绕过传统中间件管道,实现接近原生 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, 2025-12-8 23:51 , Processed in 1.258681 second(s), 44 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

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