[特殊字符] .NET 微服务网关(Ocelot)实战手册

发布于:2025-09-02 ⋅ 阅读:(21) ⋅ 点赞:(0)

🚀 .NET 微服务网关(Ocelot)实战手册

一站式路由、认证与服务治理指南

📋 适用场景

ASP.NET Core 微服务架构 | 基于 Ocelot 的 API 网关设计 | 企业级服务治理实践


📚 目录导航

序号 模块 说明
1 网关概述 为什么 .NET 微服务需要 Ocelot?
2 环境搭建 项目创建 + 依赖配置 + 目录结构
3 核心配置 路由规则 + 全局配置 + 高级特性
4 集成流程 Program.cs 配置 + 中间件顺序
5 功能实战 认证授权 + 服务发现 + 限流熔断
6 问题排查 常见错误 + 解决方案
7 最佳实践 配置分离 + 监控 + 高可用

1. 网关概述:核心价值

1.1 Ocelot 是什么?

Ocelot 是 .NET 生态专属的开源 API 网关,基于 ASP.NET Core 构建,专为微服务架构设计,已成为 .NET 微服务项目的事实标准网关方案。

1.2 解决的核心痛点

微服务拆分后,Ocelot 解决了以下 .NET 项目的典型问题:

🔗 统一入口

前端仅需访问网关地址,无需记忆多个服务的 IP:端口

🔐 集中认证

网关层统一验证 JWT 令牌,避免每个服务重复开发

⚖️ 负载均衡

自动分发请求到多实例服务,支持 Consul 服务发现

🛡️ 服务保护

限流、熔断、降级,防止服务被恶意请求压垮

1.3 .NET 微服务架构中的网关定位

flowchart TD
    subgraph 客户端层
        前端[Web前端<br>(Vue/React)]
        APP[移动端APP]
    end
    
    subgraph 网关层
        网关[Ocelot Gateway<br>https://api.example.com]
    end
    
    subgraph 服务层
        认证服务[AuthService<br>.NET 8]
        商品服务[ProductService<br>.NET 8]
        订单服务[OrderService<br>.NET 8]
    end
    
    subgraph 数据层
        数据库1[(SQL Server<br>用户库)]
        数据库2[(SQL Server<br>商品库)]
        数据库3[(SQL Server<br>订单库)]
    end

    前端 --> 网关
    APP --> 网关
    网关 --> 认证服务
    网关 --> 商品服务
    网关 --> 订单服务
    认证服务 --> 数据库1
    商品服务 --> 数据库2
    订单服务 --> 数据库3

2. 环境搭建:从零开始

2.1 项目创建

  1. 创建网关项目
    打开 Visual Studio → 新建项目 → 选择 “ASP.NET Core 空” → 命名为 OcelotGateway

  2. 安装依赖包
    通过 NuGet 包管理器安装以下核心依赖:

    # 核心网关包
    dotnet add package Ocelot --version 18.0.0
    # 服务发现(Consul 集成)
    dotnet add package Ocelot.Provider.Consul --version 18.0.0
    # Swagger 文档聚合
    dotnet add package Swashbuckle.AspNetCore.Ocelot --version 6.5.0
    # JWT 认证
    dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 8.0.0
    

2.2 项目目录结构

OcelotGateway/
├── config/                      # 配置文件目录
│   ├── ocelot.development.json  # 开发环境路由配置
│   └── ocelot.production.json   # 生产环境路由配置
├── Properties/
│   └── launchsettings.json      # 启动配置
├── appsettings.json             # 全局配置
├── appsettings.Development.json # 开发环境配置
├── Program.cs                   # 启动类
└── OcelotGateway.csproj         # 项目文件

2.3 启动配置(launchsettings.json)

确保网关端口固定(便于微服务对接):

{
  "profiles": {
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:5000;http://localhost:5001",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

3. 核心配置:ocelot.json 详解

Ocelot 的所有路由和特性都通过 ocelot.json 配置,以下是 .NET 项目的典型配置:

3.1 基础路由配置

// config/ocelot.development.json
{
  "Routes": [
    // 认证服务路由(登录/注册)
    {
      "Key": "AuthService",
      "DownstreamPathTemplate": "/api/auth/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        { "Host": "localhost", "Port": 7059 } // AuthService 端口
      ],
      "UpstreamPathTemplate": "/api/auth/{everything}",
      "UpstreamHttpMethod": ["GET", "POST"],
      "Timeout": 30000,
      "RateLimitOptions": {
        "EnableRateLimiting": true,
        "Period": "1m",
        "Limit": 100,
        "Message": "请求过于频繁,请1分钟后再试"
      }
    },
    // 商品服务路由
    {
      "Key": "ProductService",
      "DownstreamPathTemplate": "/api/products/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        { "Host": "localhost", "Port": 7060 } // ProductService 端口
      ],
      "UpstreamPathTemplate": "/api/products/{everything}",
      "UpstreamHttpMethod": ["GET", "PUT", "DELETE"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer", // 启用 JWT 认证
        "AllowedScopes": []
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://localhost:5000", // 网关对外地址
    "RequestIdKey": "X-Request-Id",
    "ServiceDiscoveryProvider": {
      "Type": "Consul", // 启用 Consul 服务发现
      "Host": "localhost",
      "Port": 8500
    }
  }
}

3.2 配置字段说明

分类 字段 说明 .NET 项目建议
下游服务 DownstreamPathTemplate 微服务接口路径 与服务的 [Route] 特性匹配
DownstreamHostAndPorts 服务地址和端口 对应 launchsettings.json 中的端口
上游请求 UpstreamPathTemplate 网关暴露的路径 建议与下游路径保持一致,简化维护
UpstreamHttpMethod 允许的 HTTP 方法 明确指定支持的方法,避免冗余
高级特性 Timeout 转发超时时间 30000ms(30秒),避免长时间阻塞
RateLimitOptions 限流配置 生产环境建议启用,保护服务
AuthenticationOptions 认证配置 非公开接口必须启用 JWT 认证

4. 集成流程:ASP.NET Core 联动

4.1 启动类配置(Program.cs)

这是网关与 ASP.NET Core 集成的核心,中间件顺序至关重要

var builder = WebApplication.CreateBuilder(args);

// 1. 加载 Ocelot 配置(按环境区分)
builder.Configuration.AddJsonFile(
    path: $"config/ocelot.{builder.Environment.EnvironmentName}.json",
    optional: false,
    reloadOnChange: true
);

// 2. 注册 Ocelot 服务
builder.Services.AddOcelot(builder.Configuration)
    .AddConsul(); // 集成 Consul 服务发现

// 3. 注册 Swagger 文档(聚合所有微服务接口)
builder.Services.AddSwaggerForOcelot(builder.Configuration, opt =>
{
    opt.GenerateDocsForGatewayItSelf = true;
    opt.SwaggerDocConfig = config =>
    {
        config.Title = "Ocelot 网关 API 文档";
        config.Version = "v1";
        config.Description = "聚合 AuthService、ProductService 等微服务接口";
    };
});

// 4. 配置 JWT 认证(网关层统一验证)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidateAudience = true,
            ValidAudience = builder.Configuration["Jwt:Audience"],
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"]!))
        };
    });

// 5. 配置跨域(允许前端访问)
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins(builder.Configuration["Cors:AllowedOrigins"]!.Split(','))
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

var app = builder.Build();

// 6. 中间件顺序(严格按此执行)
if (app.Environment.IsDevelopment())
{
    app.UseSwaggerForOcelotUI(opt =>
    {
        opt.PathToSwaggerGenerator = "/swagger/docs";
        opt.DocumentTitle = "Ocelot 网关文档";
    });
}

app.UseHttpsRedirection();       // 1. HTTPS 重定向
app.UseCors("AllowFrontend");    // 2. 跨域(必须在认证前)
app.UseAuthentication();         // 3. 认证(验证 JWT)
app.UseAuthorization();          // 4. 授权(验证权限)
await app.UseOcelot();           // 5. 启动 Ocelot 网关

app.Run();

4.2 全局配置(appsettings.json)

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Ocelot": "Information", // 启用 Ocelot 日志
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Jwt": {
    "Issuer": "https://localhost:5000",
    "Audience": "https://localhost:5173",
    "Secret": "your-32-character-strong-secret-key-here",
    "ExpiresHours": 24
  },
  "Cors": {
    "AllowedOrigins": "https://localhost:5173,http://localhost:3000"
  }
}

5. 功能实战:企业级特性

5.1 JWT 认证授权

5.1.1 配置说明
  1. 网关层启用认证:在 ocelot.json 中为需要保护的路由添加 AuthenticationOptions
  2. 服务层信任网关:微服务无需重复验证 JWT,直接从网关传递的 Claims 中获取用户信息。
5.1.2 微服务中获取用户信息
// ProductService 中的控制器
[ApiController]
[Route("api/products")]
[Authorize] // 信任网关传递的认证信息
public class ProductController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProducts()
    {
        // 从网关传递的 Claims 中获取用户 ID
        var userId = User.FindFirstValue(JwtRegisteredClaimNames.Sub);
        // 业务逻辑...
        return Ok();
    }
}

5.2 Consul 服务发现

当微服务动态扩容时,网关自动发现新实例,无需手动修改配置:

  1. 启动 Consul:本地开发可通过 Docker 启动:
    docker run -d -p 8500:8500 --name consul consul:1.15.0
    
  2. 微服务注册到 Consul:在每个微服务的 Program.cs 中添加:
    builder.Services.AddConsul(option =>
    {
        option.Address = new Uri("http://localhost:8500");
    }).AddConsulServiceRegistration(option =>
    {
        option.ID = "ProductService-" + Guid.NewGuid();
        option.Name = "ProductService";
        option.Address = "localhost";
        option.Port = 7060;
        option.Check = new AgentServiceCheck
        {
            HTTP = "https://localhost:7060/health",
            Interval = TimeSpan.FromSeconds(10)
        };
    });
    

5.3 限流与熔断

5.3.1 限流配置
"RateLimitOptions": {
  "EnableRateLimiting": true,
  "Period": "1m",          // 限流周期(1分钟)
  "Limit": 100,            // 周期内最大请求数
  "Message": "请求过于频繁,请稍后再试",
  "ClientIdHeader": "X-Client-Id" // 客户端标识头
}
5.3.2 熔断配置
"QoSOptions": {
  "ExceptionsAllowedBeforeBreaking": 5, // 允许的异常次数
  "DurationOfBreak": 30,                // 熔断时间(秒)
  "TimeoutValue": 5000                  // 请求超时时间(毫秒)
}

6. 问题排查:避坑指南

6.1 常见错误及解决方案

错误现象 可能原因 解决方案
404 Not Found 路由路径不匹配 1. 检查 UpstreamPathTemplate 与前端请求路径是否一致
2. 确认微服务已启动且端口正确
502 Bad Gateway 下游服务不可达 1. 直接访问微服务地址(如 https://localhost:7059/api/auth/login)确认服务是否正常
2. 检查微服务的 HTTPS 证书配置
401 Unauthorized JWT 验证失败 1. 确保网关与微服务的 Jwt:Secret 完全一致
2. 检查令牌是否过期或被篡改
跨域错误 CORS 配置缺失 1. 确认网关已配置 UseCorsAllowedOrigins 包含前端地址
2. 中间件顺序:UseCors 必须在 UseAuthentication

6.2 日志排查

启用 Ocelot 详细日志,快速定位问题:

// appsettings.Development.json
"Logging": {
  "LogLevel": {
    "Ocelot": "Debug", // 启用调试日志
    "Ocelot.DownstreamRouteFinder": "Debug",
    "Ocelot.DownstreamUrlCreator": "Debug"
  }
}

7. 最佳实践:生产级建议

7.1 配置管理

  1. 环境分离:开发/测试/生产环境使用不同的 ocelot.{env}.json
  2. 敏感信息加密:JWT Secret、数据库连接字符串等通过 Azure Key VaultHashiCorp Vault 存储。
  3. 动态配置:结合 Consul/K8s ConfigMap 实现配置热更新,无需重启网关。

7.2 监控与可观测性

工具 用途 集成方式
Serilog 结构化日志 配置 WriteTo.Console() + WriteTo.File()
Prometheus + Grafana 性能监控 安装 Ocelot.Metrics.Prometheus
Jaeger 分布式追踪 集成 OpenTelemetry 实现全链路追踪

7.3 高可用部署

  1. 网关集群:部署多个网关实例,通过 Nginx 做负载均衡。
  2. 健康检查:配置 Consul 健康检查,自动剔除故障网关实例。
  3. 熔断降级:对非核心服务配置熔断,保障核心服务可用。

📌 核心总结

Ocelot 作为 .NET 微服务的核心网关,通过 统一路由、集中认证、服务发现、限流熔断 四大能力,解决了微服务架构的复杂性问题。在实际项目中,需注意 中间件顺序、配置分离、监控告警 三个关键点,才能构建稳定、可扩展的生产级网关。


文档版本:v1.0.0 | 适用 Ocelot 版本:18.0.0 | 适用 .NET 版本:.NET 6/8


网站公告

今日签到

点亮在社区的每一天
去签到