后端技术14-单一架构已死?混合架构才是2026年的正确打开方式,单体+微服务+Serverless:我们的三层架构实战
CSDN多平台一键发布功能开通链接
https://mp.csdn.net/vip?utm_source=weitingfu
目录
- 开篇:架构选择的困境
- 什么是混合架构?
- 分层架构设计实践
- 核心域:单体/模块化单体
- 支撑域:微服务
- 边缘场景:Serverless
- 数据一致性保障
- 运维复杂度管理
- 实战案例:某电商平台混合架构演进
- 文末三件套
开篇:架构选择的困境
你是否经历过这样的场景?
团队开会讨论架构选型,有人高举微服务大旗,说单体是"上古遗物";有人坚持单体够用,微服务是"过度设计"。两派争得面红耳赤,最后老板一拍板:“先单体,后面再说。”
三个月后,系统复杂度飙升,单体成了"大泥球"。又开会,这次决定拆微服务。半年后,20个微服务,运维成本爆炸,一个小改动要改5个仓库…
问题出在哪?
不是单体错了,也不是微服务错了,而是用一把锤子砸所有钉子的思维错了。
2026年了,还在争论"单体 vs 微服务"就像争论"筷子 vs 刀叉"——场景不同,工具不同。真正的智慧是:不同场景用不同架构,取长补短,各得其所。
这就是混合架构(Hybrid Architecture)的核心理念。
什么是混合架构?
混合架构不是"大杂烩",而是基于领域边界的理性分层。它的设计哲学很简单:
让合适的架构,解决合适的问题。
┌─────────────────────────────────────────────────────────────┐ │ 混合架构全景图 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ │ │ │ 边缘场景 │ ← Serverless / FaaS │ │ │ (低频/突发) │ 活动页、爬虫、定时任务 │ │ └──────┬───────┘ │ │ │ │ │ ┌──────▼───────┐ │ │ │ 支撑域 │ ← 微服务 (Microservices) │ │ │ (独立演进) │ 订单、支付、库存、物流 │ │ └──────┬───────┘ │ │ │ │ │ ┌──────▼───────┐ │ │ │ 核心域 │ ← 单体 / 模块化单体 (Modular Monolith) │ │ │ (稳定高频) │ 用户、商品、搜索 │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘为什么不是单一架构?
| 架构类型 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| 单体 | 开发快、调试易、部署简 | 扩展难、技术债累积 | 核心域、稳定业务 |
| 微服务 | 独立部署、技术异构 | 复杂度高、运维重 | 支撑域、快速迭代 |
| Serverless | 按需付费、自动扩缩 | 冷启动、 vendor lock-in | 边缘场景、低频任务 |
单一架构的问题:
- 纯单体:后期难以扩展,技术栈锁定
- 纯微服务:前期成本过高,运维噩梦
- 纯 Serverless:复杂业务难以表达,调试困难
混合架构的优势:
- ✅ 核心域稳定,单体足够
- ✅ 支撑域灵活,微服务解耦
- ✅ 边缘场景省心,Serverless托管
- ✅ 成本最优,复杂度可控
分层架构设计实践
核心域:单体/模块化单体
什么是核心域?
核心域是系统的"心脏"——用户系统、商品系统、搜索系统。这些模块的特点是:
- 业务逻辑稳定,变更频率低
- 数据一致性要求高
- 性能敏感,需要本地调用
为什么不用微服务?
想象一下:用户注册要调用户服务、权限服务、积分服务、通知服务… 一次注册4个RPC调用,网络抖动一下,用户体验就崩了。
**模块化单体(Modular Monolith)**是更好的选择:
┌─────────────────────────────────────────────────────────────┐ │ 模块化单体架构示意 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ API Gateway │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────┼────────────────────────┐ │ │ │ ▼ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ 用户模块 │ │ 商品模块 │ │ 搜索模块 │ │ │ │ │ │ (User) │ │(Product)│ │ (Search)│ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ └────────────┼────────────┘ │ │ │ │ ▼ │ │ │ │ ┌─────────────┐ │ │ │ │ │ 共享数据库 │ │ │ │ │ │ (PostgreSQL)│ │ │ │ │ └─────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ 同一个进程 / 同一个部署单元 │ │ │ └─────────────────────────────────────────────────────────────┘代码结构示例:
// 模块化单体的包结构 com.example.core ├── user // 用户模块 - 独立包,禁止跨模块直接访问 │ ├── api // 对外暴露的接口 │ ├── service // 业务逻辑 │ └── repository // 数据访问 ├── product // 商品模块 │ ├── api │ ├── service │ └── repository ├── search // 搜索模块 │ ├── api │ ├── service │ └── repository └── shared // 共享基础设施 ├── config └── common关键约束:
- 模块间通过
api包暴露接口,禁止直接访问内部实现 - 数据库表按模块前缀隔离(
user_xxx,product_xxx) - 未来拆分微服务时,只需把模块打包成独立服务
支撑域:微服务
什么是支撑域?
支撑域是支撑核心业务的"器官"——订单、支付、库存、物流。这些模块的特点是:
- 业务逻辑相对独立
- 需要快速迭代,独立部署
- 团队规模扩大,需要并行开发
微服务拆分原则:
┌─────────────────────────────────────────────────────────────┐ │ 支撑域微服务架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ │ │ │ API GW │ │ │ └──────┬──────┘ │ │ │ │ │ ┌──────▼──────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ 订单服务 │ │ 支付服务 │ │ 库存服务 │ │ 物流服务 │ │ │ │ │ │ │ │ │ │ │ │ │ │ - 创建订单 │ │ - 发起支付 │ │ - 扣减库存 │ │ - 创建运单│ │ │ │ - 取消订单 │ │ - 查询状态 │ │ - 释放库存 │ │ - 轨迹查询│ │ │ │ - 订单查询 │ │ - 退款 │ │ - 库存查询 │ │ - 签收确认│ │ │ │ │ │ │ │ │ │ │ │ │ │ MySQL │ │ MySQL │ │ Redis │ │ MySQL │ │ │ └─────────────┘ └──────────┘ └──────────┘ └─────────┘ │ │ │ │ 通信方式:异步消息队列 (RabbitMQ / Kafka) │ │ │ └─────────────────────────────────────────────────────────────┘订单服务代码示例:
@Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private PaymentClient paymentClient; // Feign 调用支付服务 @Autowired private InventoryClient inventoryClient; // Feign 调用库存服务 @Autowired private RabbitTemplate rabbitTemplate; // 消息队列 /** * 创建订单 - orchestration 模式 */ @Transactional public Order createOrder(CreateOrderRequest request) { // 1. 扣减库存 boolean deducted = inventoryClient.deduct(request.getSkuId(), request.getQuantity()); if (!deducted) { throw new BizException("库存不足"); } // 2. 创建订单(本地事务) Order order = new Order(); order.setUserId(request.getUserId()); order.setSkuId(request.getSkuId()); order.setQuantity(request.getQuantity()); order.setStatus(OrderStatus.CREATED); orderRepository.save(order); // 3. 发送延迟消息(15分钟后未支付自动取消) rabbitTemplate.convertAndSend( "order.delay.exchange", "order.delay.key", new OrderDelayMessage(order.getId()), msg -> { msg.getMessageProperties().setDelay(15 * 60 * 1000); // 15分钟 return msg; } ); // 4. 异步通知物流系统预留运力 rabbitTemplate.convertAndSend( "logistics.exchange", "logistics.reserve", new ReserveLogisticsRequest(order.getId(), request.getAddress()) ); return order; } }微服务设计要点:
- 数据库独立:每个服务有自己的数据库,禁止直接访问其他服务的数据库
- 异步优先:服务间通信优先用消息队列,降低耦合
- 接口契约:使用 OpenAPI / Protobuf 定义接口,版本化管理
- 熔断降级:Hystrix / Sentinel 防止级联故障
边缘场景:Serverless
什么是边缘场景?
边缘场景是那些低频、突发、独立的任务:
- 运营活动页(一年几次大促)
- 数据爬虫(定时抓取外部数据)
- 图片处理(用户上传后生成缩略图)
- 定时报表(每天凌晨生成)
为什么用 Serverless?
这些任务如果用传统服务器部署:
- 大部分时间空闲,资源浪费
- 突发流量时需要手动扩容
- 运维成本高(监控、日志、告警)
Serverless 的优势:按需付费、自动扩缩、零运维。
┌─────────────────────────────────────────────────────────────┐ │ Serverless 场景示意 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ API Gateway │ │ │ │ (触发器:HTTP / 定时 / 事件) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────────┼────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 活动页函数 │ │ 图片处理 │ │ 数据爬虫 │ │ │ │ (Activity) │ │ (ImageProc) │ │ (Spider) │ │ │ │ │ │ │ │ │ │ │ │ 大促H5页面 │ │ 上传→压缩水印 │ │ 定时抓取竞品 │ │ │ │ 秒杀落地页 │ │ 生成多尺寸 │ │ 价格监控 │ │ │ │ │ │ │ │ │ │ │ │ 运行时长: │ │ 运行时长: │ │ 运行时长: │ │ │ │ < 100ms │ │ < 3s │ │ < 5min │ │ │ │ │ │ │ │ │ │ │ │ 调用次数: │ │ 调用次数: │ │ 调用次数: │ │ │ │ 大促时激增 │ │ 随上传量 │ │ 定时触发 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ 成本对比: │ │ - 传统ECS:24小时运行,月均 ¥500+ │ │ - Serverless:按调用付费,月均 ¥50 以下 │ │ │ └─────────────────────────────────────────────────────────────┘Serverless 函数示例(Python / AWS Lambda):
import json import boto3 from PIL import Image import io def lambda_handler(event, context): """ 图片处理函数:接收 S3 上传事件,生成缩略图 """ s3 = boto3.client('s3') # 从事件获取上传的文件信息 bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] # 下载原图 response = s3.get_object(Bucket=bucket, Key=key) image = Image.open(io.BytesIO(response['Body'].read())) # 生成缩略图 (200x200) thumbnail = image.copy() thumbnail.thumbnail((200, 200)) # 生成预览图 (800x800) preview = image.copy() preview.thumbnail((800, 800)) # 上传处理后的图片 thumbnail_buffer = io.BytesIO() thumbnail.save(thumbnail_buffer, format='JPEG', quality=85) thumbnail_buffer.seek(0) preview_buffer = io.BytesIO() preview.save(preview_buffer, format='JPEG', quality=90) preview_buffer.seek(0) # 保存到目标路径 s3.put_object( Bucket=bucket, Key=f"thumbnails/{key}", Body=thumbnail_buffer, ContentType='image/jpeg' ) s3.put_object( Bucket=bucket, Key=f"previews/{key}", Body=preview_buffer, ContentType='image/jpeg' ) return { 'statusCode': 200, 'body': json.dumps({ 'message': 'Image processed successfully', 'original': key, 'thumbnail': f"thumbnails/{key}", 'preview': f"previews/{key}" }) }Serverless 使用建议:
- 冷启动优化:使用 Provisioned Concurrency 或保持函数"温热"
- 超时设置:根据任务复杂度设置合理的超时时间
- 日志集中:使用 CloudWatch / SLS 等统一收集日志
- 避免长连接:不适合 WebSocket 等长连接场景
数据一致性保障
混合架构最大的挑战:跨架构的数据一致性。
场景:下单扣库存
用户下单时,需要同时操作:
- 订单服务:创建订单
- 库存服务:扣减库存
如果订单创建成功,库存扣减失败,就会出现超卖。
解决方案:Saga 模式
┌─────────────────────────────────────────────────────────────┐ │ Saga 分布式事务示意 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 正常流程: │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 创建订单 │───→│ 扣减库存 │───→│ 发起支付 │ │ │ │ [成功] │ │ [成功] │ │ [成功] │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ └──────────────┴──────────────┘ │ │ 事务完成 ✓ │ │ │ │ 补偿流程(扣减库存失败): │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 创建订单 │───→│ 扣减库存 │───→│ 补偿订单 │ │ │ │ [成功] │ │ [失败] │ │ [取消订单]│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ └──────────────┴──────────────┘ │ │ 事务回滚 ✓ │ │ │ └─────────────────────────────────────────────────────────────┘Saga 实现代码示例:
@Service public class OrderSagaOrchestrator { @Autowired private OrderService orderService; @Autowired private InventoryService inventoryService; @Autowired private PaymentService paymentService; /** * Saga 编排器:协调多个服务的本地事务 */ public SagaResult executeOrderSaga(CreateOrderRequest request) { List<CompensateAction> compensateActions = new ArrayList<>(); try { // Step 1: 创建订单 Order order = orderService.createOrder(request); compensateActions.add(() -> orderService.cancelOrder(order.getId())); // Step 2: 扣减库存 boolean inventoryResult = inventoryService.deduct( request.getSkuId(), request.getQuantity() ); if (!inventoryResult) { throw new BizException("库存不足"); } compensateActions.add(() -> inventoryService.release( request.getSkuId(), request.getQuantity() )); // Step 3: 发起支付(异步,不阻塞) paymentService.initiatePayment(order.getId(), request.getAmount()); return SagaResult.success(order); } catch (Exception e) { // 执行补偿操作(逆序) Collections.reverse(compensateActions); for (CompensateAction action : compensateActions) { try { action.execute(); } catch (Exception ex) { // 补偿失败,记录日志,人工介入 log.error("补偿操作失败", ex); } } return SagaResult.failure(e.getMessage()); } } @FunctionalInterface interface CompensateAction { void execute(); } }最终一致性保障策略
| 场景 | 方案 | 工具 |
|---|---|---|
| 强一致性要求 | Saga + 补偿 | 自研编排器 / Seata |
| 最终一致性 | 消息队列 + 重试 | RabbitMQ / Kafka |
| 定时对账 | 对账任务 + 人工修复 | XXL-JOB / Quartz |
运维复杂度管理
混合架构的运维挑战:三种架构,三套运维体系。
统一可观测性
┌─────────────────────────────────────────────────────────────┐ │ 统一可观测性架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 单体应用 │ │ 微服务 │ │ Serverless │ │ │ │ (核心域) │ │ (支撑域) │ │ (边缘场景) │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ └────────────────┼────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 数据采集层 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Log │ │ Metric │ │ Trace │ │ │ │ │ │(ELK/Loki)│ │(Prometheus)│ │(Jaeger) │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 统一展示层 │ │ │ │ Grafana + AlertManager │ │ │ │ 统一大盘 / 统一告警 / 统一追踪 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘日志规范(统一 JSON 格式):
{ "timestamp": "2026-01-15T10:30:00.000Z", "level": "INFO", "service": "order-service", "traceId": "abc123def456", "spanId": "span789", "message": "订单创建成功", "context": { "orderId": "ORD202601150001", "userId": "U10086", "amount": 199.99 } }部署策略
| 架构类型 | 部署方式 | 工具 |
|---|---|---|
| 单体 | 蓝绿部署 / 滚动部署 | Kubernetes Deployment |
| 微服务 | 金丝雀发布 / 灰度发布 | Istio + Flagger |
| Serverless | 直接部署 | Serverless Framework / Terraform |
实战案例:某电商平台混合架构演进
背景
某垂直电商平台,年 GMV 10亿+,技术团队 50人。
初期架构(2020年):
- 纯单体,Spring Boot + MySQL
- 日均订单 1万,系统稳定
第一次危机(2022年):
- 大促期间,订单模块性能瓶颈
- 全站发布需要 2小时,回滚困难
- 决定拆分微服务
过度拆分(2023年):
- 拆出 30+ 微服务
- 运维成本飙升,调用链路复杂
- 一次下单涉及 8 个服务 RPC 调用
混合架构改造(2024年至今):
┌─────────────────────────────────────────────────────────────┐ │ 电商平台混合架构现状 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ CDN + WAF │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────┼────────────────────────┐ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ │ │ API Gateway │ │ │ │ │ │ (Kong / Spring Cloud Gateway) │ │ │ │ │ └─────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ┌────────────┼────────────┐ │ │ │ │ ▼ ▼ ▼ │ │ │ │ ┌─────────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ 核心域单体 │ │ 支撑域微服务│ │ Serverless│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ • 用户中心 │ │ • 订单服务 │ │ • 活动页 │ │ │ │ │ │ • 商品中心 │ │ • 支付服务 │ │ • 图片处理│ │ │ │ │ │ • 搜索服务 │ │ • 库存服务 │ │ • 数据报表│ │ │ │ │ │ • 推荐引擎 │ │ • 物流服务 │ │ • 消息推送│ │ │ │ │ │ │ │ • 营销服务 │ │ │ │ │ │ │ │ 8个模块 │ │ 12个服务 │ │ 20+函数 │ │ │ │ │ │ 本地调用 │ │ 异步消息 │ │ 按需触发 │ │ │ │ │ └─────────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ 效果: │ │ - 核心接口 P99 延迟从 800ms → 120ms │ │ - 发布耗时从 2小时 → 15分钟(核心域)/ 5分钟(微服务) │ │ - 运维成本降低 40% │ │ - 服务器成本降低 30%(Serverless 替代低频任务) │ │ │ └─────────────────────────────────────────────────────────────┘关键决策点
为什么核心域保留单体?
- 用户、商品、搜索是高频核心链路,本地调用性能最优
- 这些模块变更频率低,不需要独立部署
为什么支撑域用微服务?
- 订单、支付、库存需要快速迭代,独立团队负责
- 大促期间可以单独扩容库存服务
为什么边缘场景用 Serverless?
- 活动页一年只有几次大促,Serverless 成本最低
- 图片处理是突发流量,自动扩缩容省心
文末三件套
1. 源码获取
本文涉及的代码示例已整理到 GitHub:
https://github.com/example/hybrid-architecture-demo包含:
- 模块化单体项目模板
- 微服务 Saga 实现示例
- Serverless 函数模板
- Kubernetes 部署 YAML
2. 思考题
看完本文,不妨思考以下问题:
- 你的系统现在处于哪个阶段?是单体臃肿期,还是微服务过度拆分期?
- 如果让你重新设计,你会如何划分核心域和支撑域?
- 你觉得混合架构是妥协还是智慧?欢迎在评论区讨论 👇
3. 系列预告
这是《后端架构实战》系列的第14篇,后续计划:
- 第15篇:《从 0 搭建混合架构:技术选型与项目初始化》
- 第16篇:《模块化单体拆微服务:数据迁移与双写方案》
- 第17篇:《Serverless 生产实践:冷启动优化与成本控制》
关注专栏,不错过更新!
总结
混合架构不是"和稀泥",而是基于领域边界的理性分层:
- 核心域:单体/模块化单体,追求稳定与性能
- 支撑域:微服务,追求灵活与独立演进
- 边缘场景:Serverless,追求成本与省心
架构没有银弹,适合当下的,就是最好的。
标签:#混合架构 #微服务 #单体架构 #Serverless #架构设计 #后端开发 #系统设计
互动话题:你觉得混合架构是妥协还是智慧?欢迎在评论区分享你的观点!
CSDN多平台一键发布功能开通链接
https://mp.csdn.net/vip?utm_source=weitingfu
