首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >架构演进的秘密:从小程序到亿级流量

架构演进的秘密:从小程序到亿级流量

作者头像
行者全栈架构师
发布2026-05-21 17:44:27
发布2026-05-21 17:44:27
1310
举报

开篇:一个真实的架构演进故事

2018 年,我加入了一家创业公司,负责他们的核心交易系统。

3 年时间,我亲历了这个系统从日活 500 到日活 100 万的完整演进过程。

今天,我就把这个真实案例拆解给你看,希望能帮你少走 3 年弯路

先上全貌图:


一、初期架构:单体应用(2018 年)

📌 业务背景

日活用户:500•日均订单:1000 单•峰值 QPS:500•团队规模:5 个开发

📌 技术架构

📌 核心代码结构

代码语言:javascript
复制
// 典型的三层架构
@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping
    public Result<Order> create(@RequestBody CreateOrderRequest request) {
        return orderService.create(request);
    }
}

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Transactional
    public Result<Order> create(CreateOrderRequest request) {
        // 1. 验证库存
        // 2. 创建订单
        // 3. 扣减库存
        // 4. 记录流水
        return Result.success(order);
    }
}

📌 遇到的问题

问题 1:数据库慢查询

代码语言:javascript
复制
-- 随着数据量增长,这个查询越来越慢
SELECT * FROM orders 
WHERE user_id = 123 
ORDER BY created_at DESC 
LIMIT 20;

-- 数据量:10 万 → 响应时间:50ms
-- 数据量:50 万 → 响应时间:500ms
-- 数据量:100 万 → 响应时间:2000ms

问题 2:高峰期系统崩溃

代码语言:javascript
复制
场景:双 11 活动
现象:
- 数据库连接池耗尽
- CPU 100%
- 接口超时,用户投诉

原因:
- 所有请求都打到数据库
- 没有缓存保护
- 没有限流机制

问题 3:代码耦合严重

代码语言:javascript
复制
// 一个方法 500 行,什么逻辑都有
public void createOrder() {
    // 验证用户
    // ... 50 行

    // 验证库存
    // ... 100 行

    // 计算价格(含各种优惠)
    // ... 150 行

    // 创建订单
    // ... 100 行

    // 扣减库存
    // ... 50 行

    // 发送通知
    // ... 50 行
}

二、第一次升级:读写分离 + 缓存(2019 年)

📌 触发点

日活用户:5000•日均订单:1 万单•峰值 QPS:2000•痛点:数据库扛不住了

📌 优化方案

1️⃣ 读写分离

代码改造

代码语言:javascript
复制
// 配置多数据源
@Configuration
public class DataSourceConfig {

    // 主库(写)
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 从库(读)
    @Bean
    @ConfigurationProperties("spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
}

// 使用注解区分读写
@Service
public class OrderService {

    // 写操作,走主库
    @Transactional
    @Master
    public void create(Order order) {
        orderMapper.insert(order);
    }

    // 读操作,走从库
    @Slave
    public Order getById(Long id) {
        return orderMapper.selectById(id);
    }
}

2️⃣ 引入缓存

缓存策略

代码语言:javascript
复制
@Service
public class OrderService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 查询订单:先查缓存,缓存没有再查 DB
    public Order getById(Long id) {
        String key = "order:" + id;

        // 1. 查缓存
        Order order = (Order) redisTemplate.opsForValue().get(key);
        if (order != null) {
            return order;
        }

        // 2. 查数据库
        order = orderMapper.selectById(id);

        // 3. 写入缓存(30 分钟过期)
        if (order != null) {
            redisTemplate.opsForValue().set(key, order, 30, TimeUnit.MINUTES);
        }

        return order;
    }

    // 更新订单:删除缓存
    @Transactional
    public void update(Order order) {
        orderMapper.update(order);

        // 删除缓存,保证一致性
        String key = "order:" + order.getId();
        redisTemplate.delete(key);
    }
}

3️⃣ 热点数据优化

问题:秒杀活动,大量请求查询同一个商品 解决:本地缓存 + Redis 多级缓存

代码语言:javascript
复制
@Service
public class ProductService {

    // 本地缓存(Guava Cache)
    private Cache<Long, Product> localCache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .build();

    public Product getById(Long id) {
        // 1. 本地缓存
        Product product = localCache.getIfPresent(id);
        if (product != null) {
            return product;
        }

        // 2. Redis 缓存
        String key = "product:" + id;
        product = (Product) redisTemplate.opsForValue().get(key);
        if (product != null) {
            localCache.put(id, product);
            return product;
        }

        // 3. 数据库
        product = productMapper.selectById(id);

        // 4. 写入两级缓存
        redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);
        localCache.put(id, product);

        return product;
    }
}

📌 优化效果

指标

优化前

优化后

提升

平均响应时间

500ms

50ms

10 倍

数据库 CPU

80%

30%

60% 下降

支持 QPS

500

2000

4 倍

📌 新出现的问题

问题 1:缓存击穿

代码语言:javascript
复制
场景:某个热点商品过期,大量请求同时打到 DB
解决:互斥锁 + 永不过期

问题 2:主从延迟

代码语言:javascript
复制
场景:刚下的订单,立即查询查不到(还没同步到从库)
解决:关键业务强制读主库

问题 3:缓存一致性

代码语言:javascript
复制
场景:DB 和缓存数据不一致
解决:延时双删 + 监听 binlog

三、第二次升级:微服务拆分(2020 年)

📌 触发点

日活用户:5 万•日均订单:10 万单•峰值 QPS:5000•团队规模:20 人•痛点

•代码冲突频繁•部署风险大•无法按需扩容

📌 拆分原则

代码语言:javascript
复制
1. 按业务域拆分
   - 用户、订单、支付、商品独立成服务

2. 高内聚低耦合
   - 每个服务独立数据库
   - 服务间通过 API 通信

3. 渐进式迁移
   - 先拆边缘业务
   - 再拆核心业务
   - 保持双轨运行

📌 最终架构

📌 关键技术选型

代码语言:javascript
复制
服务注册与发现:Nacos
配置中心:Nacos Config
服务调用:OpenFeign
负载均衡:Ribbon
熔断降级:Sentinel
API 网关:Spring Cloud Gateway
分布式事务:Seata
链路追踪:SkyWalking
日志收集:ELK
监控告警:Prometheus + Grafana

📌 核心代码示例

订单服务调用支付服务

代码语言:javascript
复制
// 1. 定义 Feign 客户端
@FeignClient(name = "payment-service", fallback = PaymentFallback.class)
public interface PaymentClient {

    @PostMapping("/api/payments/create")
    Result<PaymentDTO> create(@RequestBody CreatePaymentRequest request);
}

// 2. 在订单服务中使用
@Service
public class OrderService {

    @Autowired
    private PaymentClient paymentClient;

    @Transactional
    public Result<Order> create(CreateOrderRequest request) {
        // 1. 创建订单
        Order order = createOrder(request);

        // 2. 调用支付服务创建支付单(异步)
        CreatePaymentRequest payRequest = new CreatePaymentRequest();
        payRequest.setOrderId(order.getId());
        payRequest.setAmount(request.getAmount());

        // 使用 Sentinel 限流降级
        Result<PaymentDTO> payResult = paymentClient.create(payRequest);

        // 3. 发送延迟消息(30 分钟后检查支付状态)
        rabbitTemplate.convertAndSend(
            "order.delay.exchange",
            "order.check.routing",
            new OrderCheckMessage(order.getId()),
            message -> {
                message.getMessageProperties().setDelay(1800000); // 30 分钟
                return message;
            }
        );

        return Result.success(order);
    }
}

// 3. 降级处理
@Component
public class PaymentFallback implements PaymentClient {

    @Override
    public Result<PaymentDTO> create(CreatePaymentRequest request) {
        // 降级方案:记录日志,稍后重试
        log.warn("支付服务不可用,orderId: {}", request.getOrderId());
        return Result.error("支付服务繁忙,请稍后重试");
    }
}

📌 分布式事务解决方案

场景:创建订单后,调用积分服务增加积分,如何保证一致性?

方案 1:最终一致性(推荐)

代码语言:javascript
复制
@Service
public class OrderService {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Transactional
    public Result<Order> create(CreateOrderRequest request) {
        // 1. 创建订单(本地事务)
        Order order = createOrder(request);

        // 2. 发送事务消息
        rocketMQTemplate.sendMessageInTransaction(
            "order-tx-group",
            "order-created-topic",
            MessageBuilder.withPayload(order).build(),
            order
        );

        return Result.success(order);
    }
}

// 3. 积分服务监听消息,增加积分
@RocketMQMessageListener(
    topic = "order-created-topic",
    consumerGroup = "points-consumer-group"
)
@Component
public class OrderCreatedConsumer implements RocketMQListener<Order> {

    @Autowired
    private PointsService pointsService;

    @Override
    public void onMessage(Order order) {
        // 增加积分
        pointsService.addPoints(order.getUserId(), order.getAmount() / 10);
    }
}

📌 优化效果

指标

微服务前

微服务后

提升

部署频率

每周 1 次

每天多次

10 倍

故障恢复

30 分钟

5 分钟

6 倍

支持 QPS

2000

10000

5 倍

团队效率

互相阻塞

独立开发

显著提升


四、当前架构:云原生 + 容器化(2021 年至今)

📌 触发点

日活用户:100 万•日均订单:100 万单•峰值 QPS:20000+•团队规模:50 人•目标

•弹性伸缩•快速扩缩容•提升资源利用率

📌 技术架构

📌 核心优势

1. 弹性伸缩

代码语言:javascript
复制
# HPA 自动伸缩配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 5
  maxReplicas: 50
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

效果

•平时:5 个 Pod•高峰期:自动扩展到 50 个 Pod•活动结束后:自动收缩回 5 个

2. 快速故障恢复

代码语言:javascript
复制
# 健康检查配置
livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 5

效果

•Pod 挂掉后 30 秒内自动重启•流量自动切换到健康 Pod

3. 灰度发布

代码语言:javascript
复制
# Istio 流量管理
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: order-service-vs
spec:
  hosts:
  - order-service
  http:
  - match:
    - headers:
        version:
          exact: v2
    route:
    - destination:
        host: order-service
        subset: v2
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 90
    - destination:
        host: order-service
        subset: v2
      weight: 10

效果

•新版本先导入 10% 流量•观察无问题后逐步增加到 50%、100%•有问题立即回滚

📌 监控体系

代码语言:javascript
复制
数据采集层:
├─ Prometheus(指标采集)
├─ Fluentd(日志采集)
└─ Jaeger(链路追踪)

数据存储层:
├─ Prometheus TSDB
├─ Elasticsearch
└─ ClickHouse

数据展示层:
├─ Grafana(监控大盘)
├─ Kibana(日志分析)
└─ SkyWalking(链路追踪)

告警层:
└─ AlertManager(告警管理)
    ├─ 邮件通知
    ├─ 钉钉通知
    └─ 电话通知

📌 最终效果对比

指标

初期

当前

提升倍数

日活用户

500

100 万

2000 倍

日均订单

1000

100 万

1000 倍

峰值 QPS

500

20000

40 倍

平均响应时间

500ms

50ms

10 倍

可用性

95%

99.99%

显著提升

部署频率

每周 1 次

每天 10+ 次

70 倍


五、经验总结

✅ 心得 1:架构是演进出来的

不要一开始就设计完美的架构,而是根据业务发展逐步演进

错误做法:

•只有 100 个用户,就设计支持亿级的架构•为了未来可能的需求,过度设计

正确做法:

•满足当前需求,预留扩展空间•出现问题再优化,小步快跑


✅ 心得 2:合适的才是最好的

不要盲目追求新技术,适合业务阶段的才是最好的

单体架构 ≠ 落后 微服务 ≠ 先进

关键看:

•团队能力是否匹配•业务是否需要•ROI 是否划算


✅ 心得 3:技术是为业务服务的

脱离业务谈架构,都是耍流氓

每次架构升级前,问自己:

1.业务遇到了什么瓶颈?2.现有技术哪里不满足?3.升级后的收益是什么?4.成本和风险可控吗?


✅ 心得 4:稳定性压倒一切

再好的架构,不稳定也是零

保障措施:

•限流降级(Sentinel)•熔断机制(Hystrix)•监控告警(Prometheus)•灰度发布(Istio)•容灾备份(多机房)


六、总结

回顾这 3 年的架构演进之路,我用一句话总结:

架构没有银弹,只有不断迭代

你的架构演进路径应该是:

代码语言:javascript
复制
单体架构 → 读写分离 → 微服务 → 云原生
   ↓           ↓          ↓         ↓
 活下来    性能优化    效率提升    弹性伸缩

最后送给大家一句话:

好的架构不是设计出来的,是在解决一个又一个问题的过程中成长出来的


互动环节

💬 留言区见

1.你现在的系统处于哪个阶段?2.你在架构演进中遇到过哪些坑?3.这篇文章对你有启发吗?

📢 下期预告: 明天分享《阿里 P8 推荐的 10 条技术选型原则》,聊聊如何做技术决策,敬请期待!


关于作者

全栈架构师,10 年技术从业经验,现任某互联网公司技术负责人。擅长 Spring Boot、Vue3、微服务架构。致力于分享实战干货,帮助更多工程师快速成长。


本文原创,转载请注明出处 如果觉得有用,请点个"在看"支持一下 👇

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 行者架构谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开篇:一个真实的架构演进故事
  • 一、初期架构:单体应用(2018 年)
    • 📌 业务背景
    • 📌 技术架构
    • 📌 核心代码结构
    • 📌 遇到的问题
  • 二、第一次升级:读写分离 + 缓存(2019 年)
    • 📌 触发点
    • 📌 优化方案
    • 1️⃣ 读写分离
    • 2️⃣ 引入缓存
    • 3️⃣ 热点数据优化
    • 📌 优化效果
    • 📌 新出现的问题
  • 三、第二次升级:微服务拆分(2020 年)
    • 📌 触发点
    • 📌 拆分原则
    • 📌 最终架构
    • 📌 关键技术选型
    • 📌 核心代码示例
    • 📌 分布式事务解决方案
    • 📌 优化效果
  • 四、当前架构:云原生 + 容器化(2021 年至今)
    • 📌 触发点
    • 📌 技术架构
    • 📌 核心优势
    • 📌 监控体系
    • 📌 最终效果对比
  • 五、经验总结
    • ✅ 心得 1:架构是演进出来的
    • ✅ 心得 2:合适的才是最好的
    • ✅ 心得 3:技术是为业务服务的
    • ✅ 心得 4:稳定性压倒一切
  • 六、总结
  • 互动环节
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档