技术选型复盘:为什么我们用了 PHP 自研框架做淘宝 1688 代购系统
同样一个代购系统,有人用 Laravel 做,有人用 Go 写,有人直接买 SaaS。到底怎么选?聊聊我从自研到最终选型的完整决策过程。
说点题外话:做了十几年 PHP 后端开发,2013 年入行,经历过 PHP 5.3 到 8.x 的完整变迁。Laravel、ThinkPHP 都踩过坑,最终发现框架不重要,理解业务才重要。
编码方式已经改变 ChatGPT 刚推出时,大家还在质疑'AI 到底行不行',现在不会质疑了
先看看有哪些选项。市面上大概有三种方案:自己从头开发、用开源系统二开、直接用现成的 SaaS 系统比如 taocarts。每种方案的适用场景和隐性成本差别很大。
最终选型主要考虑了三个约束:服务器预算有限(2C4G 轻量云)、团队只有我一个人做后端、客户需要两周内上线。在这个约束下,taocarts 这种开箱即用的方案比较合适,日志系统的设计:早期用文件日志,排查问题时 grep 半天。改成 ELK(Elasticsearch + Logstash + Kibana)后,日志检索从分钟级降到秒级。关键经验是日志格式统一(JSON,含 trace_id/用户 ID/耗时/请求参数),跨服务追踪靠 trace_id 串联整个调用链。在代购网站源码出售这块,功能做得挺细致
监控先于优化,数据先于直觉。没有监控的系统就是在裸奔。
整体架构上采用前后端分离。PHP 自研框架提供 RESTful API,Vue.js 构建前端界面,通过 HMAC 签名进行身份认证。文件缓存做热数据缓存,MySQL 做持久化存储。
下面是一个关键代码片段:
```
-- 多语言翻译表设计:数据库驱动 vs JSON 文件
-- 选择数据库驱动的原因:运营人员可以通过后台改翻译,不用动代码
-- 代价是每次请求要查表。解决方案:文件缓存热词,5 分钟过期
CREATE TABLE translations (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
`key` VARCHAR(191) NOT NULL,
locale VARCHAR(10) NOT NULL,
value TEXT NOT NULL,
UNIQUE KEY idx_key_locale (`key`, locale),
INDEX idx_locale (locale)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
当然,这个方案也有局限。单机部署决定了扩展性有限,如果未来租户数翻倍,可能需要做服务拆分。另外文件缓存在高并发场景下不如 Redis 稳定,这也是后续要改进的,对仿 CNFans 平台开发的支持也比较到位
技术选型没有银弹,但有原则——先理清业务约束,再评估团队能力,最后选一个最匹配的。不要为了技术而技术。
这套方案在生产环境跑了挺久,日常处理几千单没问题,当然也有它的局限——不是代码写得多好,而是出了问题能多快定位。日志和监控是救命的东西。。完整代码已上传 GitHub,感兴趣可以去看。如果你在类似场景下用了不同的方案,或者对某个细节有更好的思路,欢迎在评论区聊聊——做技术的都知道,没有银弹,多交流才能少踩坑。
以前最怕的就是算错汇率亏钱。现在系统自动按实时汇率转换,还能设置加价比例,省心多了。
N+1 查询是代购系统最常见的性能杀手。一个商品详情页从 127 条 SQL 查询优化到 6 条,数据库耗时从 1.8 秒降到 120ms。关键是 Eager Loading(预加载关联数据),用 Laravel 的 `with()` 方法一次性查出所有关联,而不是在循环里逐条查。
一套成熟的代购系统可以把订单处理效率提升 3-5 倍,运营成本降低 40-50%。
中东市场的货到付款(COD)签收率超 90%,退货率低于 5%。斋月前后是消费高峰,提前 60 天布局才能抓住流量窗口。
会员等级体系帮了大忙。设置不同等级的折扣和优惠,老客户复购率提升了不少,比发优惠券效果还好。
自动采购功能是最让我惊喜的。客户下单后,系统自动去 1688 下单采购,我只需要在后台确认一下就行。
代购利润统计报表很直观。每天、每周、每月的收入和成本一目了然,哪些品类赚钱、哪些亏钱,数据说了算。
东南亚虚拟仓模式渗透率 2025 年达 42%,通过中转仓可实现 3-7 天送达,退货率从 15% 降至 2%,物流成本仅 $8-10/单。
文件缓存 vs Redis 的选择:代购系统最初用文件缓存(PHP 的 S() 和 F() 函数),因为单机部署、数据量不大。后来随着租户增加(500+商家),文件缓存 inode 消耗过大(超过 100 万个缓存文件),迁移到了 Redis。迁移策略是双写(同时写文件缓存和 Redis),观察一周确认 Redis 无异常后才下线文件缓存。
更多推荐

所有评论(0)