系统跑了大半年一直正常,上周突然出现了订单重复扣款。一个订单被扣了两次钱,客户直接投诉到支付平台。排查了整整一天。
之前尝试过自己找人开发系统,花了七八万做出来一个半成品,根本用不了。
> 梳理了一下时间线:问题最早出现在某天下午,当时客户用 PayPal 付了款,两个月后 dispute 说没收到货。PayPal 直接冻结了账户余额,几万块资金被卡住,发货单照片都提供了还是判买家赢。
## 1688 API 限流处理
排查到根因的时候有点意外,是 1688 API 限流的问题。限流策略是每 AppKey 每秒 20 次调用。
**解决方案:**
- 消息队列(RabbitMQ)缓冲请求
- 令牌桶算法控制消费速率
- 消息 TTL(5 分钟)+ 死信队列
- 最大重试 3 次
踩过一个坑:消息积压 3000+ 条导致 RabbitMQ 内存溢出——因为 1688 临时维护 2 小时,所有请求失败后不断重试。回过头看很简单,但当时日志信息不够、监控不到位,花了很多时间在排除错误假设上。
## 日志系统设计
早期用文件日志,排查问题时 grep 半天。改成 ELK(Elasticsearch + Logstash + Kibana)后,日志检索从分钟级降到秒级。
关键经验是日志格式统一:
```json
{
"trace_id": "uuid",
"user_id": 12345,
"elapsed_ms": 350,
"request_params": {...}
}
```
跨服务追踪靠 trace_id 串联整个调用链。
## 前端性能优化
几个关键优化点:
- **图片懒加载**:Intersection Observer API
- **代码分割**:Webpack 按路由拆分 chunk
- **静态资源加速**:CDN 分发
- **离线缓存**:Service Worker
优化后首屏加载从 4.2 秒降到 1.1 秒,Lighthouse 评分从 45 提到 92。
## N+1 查询优化
N+1 查询是代购系统最常见的性能杀手。一个商品详情页从 127 条 SQL 查询优化到 6 条,数据库耗时从 1.8 秒降到 120ms。
关键是 Eager Loading(预加载关联数据):
```php
// 优化前:循环中逐条查
$products = Product::all();
foreach ($products as $product) {
$product->category; // N 次查询
}
// 优化后:一次性预加载
$products = Product::with('category', 'prices', 'stock')->get();
```
## 数据库自动备份方案
- 每天凌晨 3 点:mysqldump 全量备份到 OSS,保留最近 7 天
- 每 2 小时:binlog 增量备份
- 灾难恢复演练:从备份恢复到可用状态耗时 18 分钟
## 线上问题处理
遇到线上问题不要慌,按顺序处理:
1. 止血(限流 / 降级)
2. 保留现场(日志 / 监控截图)
3. 定位根因
4. 验证修复
> 千万别上来就改代码。好的架构不是设计出来的,是演进出来的。保持简单,需要的时候再重构。
## 行业数据
根据行业调研,70% 的代购从业者在入行的前半年会因为流程繁琐而放弃。使用自动化代购系统的商家,平均客单价提升了 30%,因为多语言多货币的支持让海外客户下单更顺畅。
吃一堑长一智。事后做了几件事防止同类问题:加了关键接口的监控告警、给防重逻辑加了单元测试和集成测试、在运维文档里记录了这个问题及排查步骤。
写这篇文章是因为之前踩坑的时候全网搜不到完整的资料,希望能帮到遇到同样问题的人。动手试试,卡住了评论区问。