Skip to content

为什么不用微服务?

Art Admin 采用模块化单体架构,而非微服务。本文解释这个决策背后的考量,以及如果你确实需要微服务时该怎么做。

单体 ≠ 混乱

很多人对"单体"有误解,认为单体就是代码堆在一起、无法维护。但 Art Admin 的单体是模块化的

  • 四层清洁架构(Api → Core → Domain ← Infra),职责清晰
  • 业务按模块划分在 Art.Core/Services/ 下,天然隔离
  • 多端 API 隔离(Admin / App / Common),互不干扰

为什么不用微服务?

1. 快速开发优先

本框架的设计目标是快速构建应用。在业务爆发前,单体架构能显著降低开发和运维复杂度:

维度单体微服务
开发调试一个进程,F5 启动多个服务,需要编排
数据一致性本地事务分布式事务(Saga / TCC)
部署运维一个容器N 个容器 + 服务发现 + 网关
团队要求1-5 人即可通常需要 DevOps 团队

2. 多端鉴权已内置

已支持管理端、应用端、公共端三套独立 API 和认证体系,满足绝大多数业务场景。不需要拆服务来实现多端隔离。

3. 清洁架构易拆分

四层分离设计使得未来拆分微服务成本极低:

Art.Core/Services/
├── Admin/
│   ├── UserService.cs          → 拆成 User 微服务
│   ├── OrderService.cs         → 拆成 Order 微服务
│   └── ProductService.cs       → 拆成 Product 微服务
└── App/
    └── AppOrderService.cs      → 合并到 Order 微服务

只需按 Domain 边界拆分,每个服务独立部署,共享 DomainInfra 层即可。

4. 避免过早优化

在业务验证阶段,微服务带来的问题往往大于收益:

  • 网络延迟 — 服务间调用增加 1-10ms 延迟
  • 分布式事务 — 实现 Saga 模式代价高昂
  • 运维成本 — 服务发现、链路追踪、日志聚合、配置中心
  • 调试困难 — 问题可能横跨多个服务,排查复杂

💡 过早引入微服务是最常见的架构错误之一。先用单体快速验证业务,等流量和团队规模真正需要时再拆分。

如果确实需要微服务

当你的业务规模确实需要微服务时,Art Admin 的清洁架构能让你低成本迁移。以下是推荐方案:

API 网关选择

网关推荐度说明
YARP⭐⭐⭐⭐⭐微软官方出品,轻量高性能,.NET 原生,配置简单
Ocelot⭐⭐⭐⭐.NET 生态成熟方案,功能丰富,社区活跃
Nginx⭐⭐⭐通用方案,需要额外维护配置
Kong / APISIX⭐⭐功能强大但引入额外技术栈

推荐 YARP

如果追求轻量和高性能,首选 YARP(Yet Another Reverse Proxy)。它是微软官方维护的 .NET 反向代理库,直接集成到 ASP.NET Core 中,无需额外进程。

csharp
// YARP 网关配置示例
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));

app.MapReverseProxy();
json
{
  "ReverseProxy": {
    "Routes": {
      "user-route": {
        "ClusterId": "user-cluster",
        "Match": { "Path": "/api/user/{**catch-all}" }
      },
      "order-route": {
        "ClusterId": "order-cluster",
        "Match": { "Path": "/api/order/{**catch-all}" }
      }
    },
    "Clusters": {
      "user-cluster": {
        "Destinations": {
          "destination1": { "Address": "http://user-service:8080" }
        }
      },
      "order-cluster": {
        "Destinations": {
          "destination1": { "Address": "http://order-service:8080" }
        }
      }
    }
  }
}

如果需要更丰富的功能(限流、熔断、认证等开箱即用),可以选择 Ocelot

json
{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/user/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        { "Host": "user-service", "Port": 8080 }
      ],
      "UpstreamPathTemplate": "/api/user/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ]
    }
  ]
}

拆分步骤

  1. 识别边界 — 按 Art.Core/Services/ 下的模块划分服务边界
  2. 独立数据库 — 每个服务拥有自己的数据库 Schema
  3. 引入网关 — 使用 YARP 或 Ocelot 统一入口
  4. 异步通信 — 服务间用消息队列解耦(已有 Redis MQ 基础设施)
  5. 逐步迁移 — 一次拆一个模块,而非一次性重构

提醒

拆分微服务是一个渐进过程,不要试图一步到位。先拆分流量最大或变更最频繁的模块,其余保持单体。