.NET 8 微服务从0到1实战指南

1 阅读4分钟

.NET 8 微服务从0到1实战指南

项目概述

本教程完整演示了如何使用 .NET 8 从零搭建一个微服务架构,包含 API 网关、认证服务、产品服务和订单服务四个核心组件。

架构设计

服务组成

服务名称端口技术栈主要职责
API 网关5001Ocelot统一入口、路由转发、集中认证
认证服务5002JWT用户认证、Token 颁发
订单服务5003.NET 8 WebAPI订单业务逻辑
产品服务5004.NET 8 WebAPI产品信息管理

架构流程图

客户端 → API网关(5001) → 路由分发 ├→ 认证服务(5002): /gateway/auth/* ├→ 产品服务(5004): /gateway/products/* └→ 订单服务(5003): /gateway/orders/*

详细实现步骤

第一步:环境准备与项目创建

1. 创建解决方案
dotnet new sln -n MicroservicesDemo
cd MicroservicesDemo
​
# 创建四个微服务项目
dotnet new webapi -n APIGateway
dotnet new webapi -n AuthService
dotnet new webapi -n ProductService
dotnet new webapi -n OrderService
​
# 添加到解决方案
dotnet sln add APIGateway/APIGateway.csproj
dotnet sln add AuthService/AuthService.csproj
dotnet sln add ProductService/ProductService.csproj
dotnet sln add OrderService/OrderService.csproj
2. 配置各服务端口

修改每个项目的 Properties/launchSettings.json

  • APIGateway: 5001
  • AuthService: 5002
  • OrderService: 5003
  • ProductService: 5004

第二步:配置 API 网关 (Ocelot)

1. 安装 Ocelot
dotnet add APIGateway package Ocelot

json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/Product",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5004
        }
      ],
      "UpstreamPathTemplate": "/gateway/products",
      "UpstreamHttpMethod": [ "GET", "POST" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer"
      }
    },
    {
      "DownstreamPathTemplate": "/api/Order",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5003
        }
      ],
      "UpstreamPathTemplate": "/gateway/orders",
      "UpstreamHttpMethod": [ "GET", "POST" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer"
      }
    },
    {
      "DownstreamPathTemplate": "/api/Auth/login",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5002
        }
      ],
      "UpstreamPathTemplate": "/gateway/auth/login",
      "UpstreamHttpMethod": [ "POST" ]
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5001"
  }
}
3. 配置网关程序 Program.cs

csharp

var builder = WebApplication.CreateBuilder(args);
​
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
​
// 加载 Ocelot 配置
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
​
// 配置 JWT 认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer", options =>
    {
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "AuthService",
            ValidAudience = "MicroservicesDemo",
            IssuerSigningKey = new       SymmetricSecurityKey(Encoding.UTF8.GetBytes("ThisIsMySuperSecretKeyForJWTTokenGenerationInMicroservicesDemo2024!"))
        };
    });
​
builder.Services.AddAuthorization();
builder.Services.AddOcelot();
​
var app = builder.Build();
​
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
​
app.UseAuthentication();
app.UseAuthorization();
​
// Ocelot 必须在最后
await app.UseOcelot();
​
app.Run();

第三步:实现认证服务

1. 安装 JWT 包

bash

dotnet add AuthService package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add AuthService package System.IdentityModel.Tokens.Jwt
2. 配置认证服务 Program.cs

csharp

var builder = WebApplication.CreateBuilder(args);
​
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
​
// 配置 JWT 认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "AuthService",
            ValidAudience = "MicroservicesDemo",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"))
        };
    });
​
builder.Services.AddAuthorization();
​
var app = builder.Build();
​
// ... 中间件配置
app.Run();
3. 实现登录控制器 AuthController.cs

csharp

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginModel model)
    {
        if (model.Username == "demo" && model.Password == "password")
        {
            // JWT Token 生成逻辑
            var token = GenerateJwtToken(model.Username);
            return Ok(new { Token = token });
        }
        return Unauthorized();
    }
    
    private string GenerateJwtToken(string username)
    {
        // Token 生成实现
    }
}

第四步:实现业务服务

产品服务 ProductController.cs

csharp

[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
    private static readonly List<Product> _products = new()
    {
        new Product { Id = 1, Name = "Laptop", Price = 55000 },
        new Product { Id = 2, Name = "Mobile", Price = 18000 }
    };
​
    [HttpGet]
    public IActionResult Get() => Ok(_products);
​
    [HttpGet("{id}")]
    public IActionResult GetById(int id)
    {
        var product = _products.Find(p => p.Id == id);
        return product == null ? NotFound() : Ok(product);
    }
}
订单服务 OrderController.cs

csharp

[ApiController]
[Route("api/[controller]")]
public class OrderController : ControllerBase
{
    private readonly IProductServiceClient _productServiceClient;

    public OrderController(IProductServiceClient productServiceClient)
    {
        _productServiceClient = productServiceClient;
    }

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] CreateOrderRequest request)
    {
        // 调用产品服务验证产品
        var product = await _productServiceClient.GetProductByIdAsync(request.ProductId);
        if (product == null)
            return BadRequest(new { message = "产品不存在" });

        // 创建订单逻辑
        var order = new Order { /* ... */ };
        return CreatedAtAction(nameof(Get), order);
    }
}

第五步:实现服务间通信

1. 配置 HttpClient

OrderService/Program.cs 中:

csharp

builder.Services.AddHttpClient("ProductService", client =>
{
    client.BaseAddress = new Uri("http://localhost:5004/");
});
builder.Services.AddScoped<IProductServiceClient, ProductServiceClient>();
2. 实现服务客户端 ProductServiceClient.cs

csharp

public class ProductServiceClient : IProductServiceClient
{
    private readonly HttpClient _httpClient;

    public ProductServiceClient(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient("ProductService");
    }

    public async Task<Product> GetProductByIdAsync(int productId)
    {
        var response = await _httpClient.GetAsync($"/api/Product/{productId}");
        if (response.IsSuccessStatusCode)
        {
            var content = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<Product>(content);
        }
        return null;
    }
}

测试流程

1. 启动所有服务

bash

dotnet run --project APIGateway
dotnet run --project AuthService
dotnet run --project OrderService  
dotnet run --project ProductService

2. 完整测试流程

bash

# 1. 获取 Token
POST http://localhost:5001/gateway/auth/login
{
  "username": "demo",
  "password": "password"
}

# 2. 访问产品列表(需要认证)
GET http://localhost:5001/gateway/products
Authorization: Bearer <your-token>

# 3. 创建订单(服务间调用)
POST http://localhost:5001/gateway/orders
Authorization: Bearer <your-token>
{
  "productId": 1,
  "quantity": 2
}

关键问题与解决方案

1. Ocelot 路由配置

问题: 路由重复或路径不匹配 解决: 确保 DownstreamPathTemplate 与控制器路由完全匹配

2. 中间件顺序

问题: 404 或认证失败 解决: 确保中间件顺序正确:

csharp

app.UseSwagger();
app.UseSwaggerUI();
app.UseAuthentication();
app.UseAuthorization();
await app.UseOcelot();  // 必须在最后

3. 服务间通信

问题: HttpClient 配置错误 解决: 正确注册命名 HttpClient 和依赖注入

核心要点总结

  1. 网关配置: Ocelot 作为统一入口,负责路由和认证
  2. 认证流程: JWT Token 的生成和验证
  3. 服务隔离: 每个服务独立部署和运行
  4. 服务通信: 通过 HttpClient 实现服务间调用
  5. 配置管理: 每个服务有自己的配置和端口

扩展方向

这个基础架构可以进一步扩展:

  1. 服务发现: 集成 Consul 或 Eureka
  2. 配置中心: 使用 Spring Cloud Config
  3. 熔断器: 集成 Polly 实现弹性调用
  4. 监控追踪: 集成 OpenTelemetry
  5. 容器化: 使用 Docker 部署
  6. 消息队列: 集成 RabbitMQ 或 Azure Service Bus

成果验证

完成本教程后,你将拥有:

  • ✅ 完整的微服务架构
  • ✅ JWT 认证系统
  • ✅ API 网关路由
  • ✅ 服务间通信
  • ✅ 可扩展的项目结构