
2018 年,我加入了一家创业公司,负责他们的核心交易系统。
3 年时间,我亲历了这个系统从日活 500 到日活 100 万的完整演进过程。
今天,我就把这个真实案例拆解给你看,希望能帮你少走 3 年弯路。
先上全貌图:

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

// 典型的三层架构
@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:数据库慢查询
-- 随着数据量增长,这个查询越来越慢
SELECT * FROM orders
WHERE user_id = 123
ORDER BY created_at DESC
LIMIT 20;
-- 数据量:10 万 → 响应时间:50ms
-- 数据量:50 万 → 响应时间:500ms
-- 数据量:100 万 → 响应时间:2000ms问题 2:高峰期系统崩溃
场景:双 11 活动
现象:
- 数据库连接池耗尽
- CPU 100%
- 接口超时,用户投诉
原因:
- 所有请求都打到数据库
- 没有缓存保护
- 没有限流机制问题 3:代码耦合严重
// 一个方法 500 行,什么逻辑都有
public void createOrder() {
// 验证用户
// ... 50 行
// 验证库存
// ... 100 行
// 计算价格(含各种优惠)
// ... 150 行
// 创建订单
// ... 100 行
// 扣减库存
// ... 50 行
// 发送通知
// ... 50 行
}•日活用户:5000•日均订单:1 万单•峰值 QPS:2000•痛点:数据库扛不住了

代码改造:
// 配置多数据源
@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);
}
}缓存策略:
@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);
}
}问题:秒杀活动,大量请求查询同一个商品 解决:本地缓存 + Redis 多级缓存
@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:缓存击穿
场景:某个热点商品过期,大量请求同时打到 DB
解决:互斥锁 + 永不过期问题 2:主从延迟
场景:刚下的订单,立即查询查不到(还没同步到从库)
解决:关键业务强制读主库问题 3:缓存一致性
场景:DB 和缓存数据不一致
解决:延时双删 + 监听 binlog•日活用户:5 万•日均订单:10 万单•峰值 QPS:5000•团队规模:20 人•痛点:
•代码冲突频繁•部署风险大•无法按需扩容
1. 按业务域拆分
- 用户、订单、支付、商品独立成服务
2. 高内聚低耦合
- 每个服务独立数据库
- 服务间通过 API 通信
3. 渐进式迁移
- 先拆边缘业务
- 再拆核心业务
- 保持双轨运行
服务注册与发现:Nacos
配置中心:Nacos Config
服务调用:OpenFeign
负载均衡:Ribbon
熔断降级:Sentinel
API 网关:Spring Cloud Gateway
分布式事务:Seata
链路追踪:SkyWalking
日志收集:ELK
监控告警:Prometheus + Grafana订单服务调用支付服务:
// 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:最终一致性(推荐)
@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 倍 |
团队效率 | 互相阻塞 | 独立开发 | 显著提升 |
•日活用户:100 万•日均订单:100 万单•峰值 QPS:20000+•团队规模:50 人•目标:
•弹性伸缩•快速扩缩容•提升资源利用率

1. 弹性伸缩
# 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. 快速故障恢复
# 健康检查配置
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. 灰度发布
# 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%•有问题立即回滚
数据采集层:
├─ 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 倍 |
不要一开始就设计完美的架构,而是根据业务发展逐步演进
错误做法:
•只有 100 个用户,就设计支持亿级的架构•为了未来可能的需求,过度设计
正确做法:
•满足当前需求,预留扩展空间•出现问题再优化,小步快跑
不要盲目追求新技术,适合业务阶段的才是最好的
单体架构 ≠ 落后 微服务 ≠ 先进
关键看:
•团队能力是否匹配•业务是否需要•ROI 是否划算
脱离业务谈架构,都是耍流氓
每次架构升级前,问自己:
1.业务遇到了什么瓶颈?2.现有技术哪里不满足?3.升级后的收益是什么?4.成本和风险可控吗?
再好的架构,不稳定也是零
保障措施:
•限流降级(Sentinel)•熔断机制(Hystrix)•监控告警(Prometheus)•灰度发布(Istio)•容灾备份(多机房)
回顾这 3 年的架构演进之路,我用一句话总结:
架构没有银弹,只有不断迭代
你的架构演进路径应该是:
单体架构 → 读写分离 → 微服务 → 云原生
↓ ↓ ↓ ↓
活下来 性能优化 效率提升 弹性伸缩最后送给大家一句话:
好的架构不是设计出来的,是在解决一个又一个问题的过程中成长出来的
💬 留言区见:
1.你现在的系统处于哪个阶段?2.你在架构演进中遇到过哪些坑?3.这篇文章对你有启发吗?
📢 下期预告: 明天分享《阿里 P8 推荐的 10 条技术选型原则》,聊聊如何做技术决策,敬请期待!
关于作者
全栈架构师,10 年技术从业经验,现任某互联网公司技术负责人。擅长 Spring Boot、Vue3、微服务架构。致力于分享实战干货,帮助更多工程师快速成长。
本文原创,转载请注明出处 如果觉得有用,请点个"在看"支持一下 👇