代购转运系统崩了三次后,我学到的 SLA 设计教训
去年双十一,凌晨两点,手机震了。
不是订单提醒——是报警群。代购转运系统的支付回调全挂了。我翻了个身,没继续睡。因为我知道,这一翻,可能就是几万块的损失。
那是我做代购系统第三年,自认为系统够稳了。结果 1688 的 API 签名算法一过期,十几个订单卡在“已支付未采购”状态。客户在群里 @我,客服电话被打爆。最惨的是,有个客户囤了十几单的日用品,等着转运到东京,结果系统卡了两天。
后来复盘,发现根本不是技术问题,是 SLA 设计的问题。
第一个教训:别把单点当高可用
我们最早的系统架构很简单:一台服务器跑所有服务,数据库也在一台机器上。当时觉得,代购转运嘛,又不是银行,崩了就重启呗。
结果有次服务器硬盘坏了,数据恢复花了三天。那三天,客户在群里骂,我们在机房哭。
后来学乖了:数据库做主从,应用层做负载均衡,关键服务做冗余。但最核心的教训是——别等出事了才想高可用,成本不是问题,信任才是。
第二个教训:API 限流不是限制,是保护
做代购转运,最怕的就是 1688 接口限流。有次我们一个活动,瞬间涌入几百单,系统疯狂调 1688 的采购接口。结果 1688 直接把我们 IP 封了,所有订单都卡在“采购中”。
那之后我们做了个简单的限流队列:每秒最多调 10 次接口,超出的排队。虽然下单慢了点,但至少不会全崩。
就像餐厅后厨的动线设计,以前靠经验,现在靠系统规划。订单管理也是一个道理。
第三个教训:汇率缓冲不是可有可无
这个教训最贵。
有次日元突然升值,我们没做汇率缓冲,所有订单的利润直接被吃掉。客户按之前的汇率付款,我们按新的汇率采购,一单亏几十块。几百单下来,一个月白干。
后来在系统里加了汇率缓冲机制:设置一个汇率波动范围,超出范围自动暂停下单,通知人工确认。虽然偶尔会延迟,但至少不亏钱。
现在怎么做
后来上了套系统,对账不用熬夜了。叫什么不重要,好用就行。
但核心还是那几个原则:
-
SLA 不是写在纸上的,是写在代码里的——99.9%的可用性,意味着一年只能崩 8 小时。你算过自己系统能撑多久吗?
-
降级比完美更重要——支付回调失败?先让订单进入待处理队列,别让客户干等。采购接口限流?先保存订单,等恢复后自动重试。
-
监控比开发更重要——没有报警的系统,等于没有保险的车。你永远不知道什么时候会出事。
技术实现的几个关键点
// 简单的限流队列实现
class RateLimiter
{
private int $maxCalls;
private int $period;
private array $calls = [];
public function __construct(int $maxCalls = 10, int $period = 1)
{
$this->maxCalls = $maxCalls;
$this->period = $period;
}
public function canCall(): bool
{
$now = time();
// 清理过期记录
$this->calls = array_filter($this->calls, fn($t) => $t > $now - $this->period);
if (count($this->calls) < $this->maxCalls) {
$this->calls[] = $now;
return true;
}
return false;
}
}
// 汇率缓冲检测
function checkExchangeRateBuffer(float $currentRate, float $baseRate, float $bufferPercent): array
{
$diff = abs($currentRate - $baseRate) / $baseRate * 100;
if ($diff > $bufferPercent) {
return [
'status' => 'paused',
'message' => "汇率波动超过{$bufferPercent}%,需人工确认",
'currentRate' => $currentRate,
'baseRate' => $baseRate,
];
}
return [
'status' => 'normal',
'message' => '汇率在安全范围内',
];
}
最后说一句
晚上十点,你刚躺下,手机震了。现在——你翻个身,继续睡。
能做到这一点的系统,才是好系统。
关于作者
老张,十年跨境系统架构师。做过代购转运、反向海淘、跨境支付。踩过的坑比写过的代码多。现在主要研究如何让系统少崩几次,让自己多睡几小时。
本文首发于华为云开发者社区,内容仅代表作者个人经验分享。
- 点赞
- 收藏
- 关注作者
评论(0)