去年年中,我们接手了一个垂直行业的SaaS项目——为中小型物流企业提供订单管理、车辆调度和财务对账的一体化平台。客户是长三角一家有10年经验的物流公司,老板亲自拍板,预算120万,工期6个月。我当时是项目负责人,技术栈选型、团队搭建、进度把控都由我拍板。
1. 初期:需求确认与第一版技术选型
客户最初的需求文档有40页,核心功能模块包括:订单录入、调度排班、在途跟踪、财务结算、报表统计。客户强调“要能支持未来5年的业务增长”,但当时他们的日均订单量只有500单左右。
我做了个决定:前后端分离 + 单体应用起步,数据库用MySQL + Redis缓存。为什么不用微服务?第一,团队只有6个人,微服务维护成本太高;第二,业务逻辑耦合度低,单体足够。前端选了Vue3 + Element Plus,后端Spring Boot 2.6,部署在阿里云ECS上。
第一个月,我们写了2000行核心代码,跑通了订单流转和基础权限。客户很满意,但问题很快来了。
2. 中期:需求变更与第一次重构
第三个月,客户突然提出:需要支持多运输模式(零担、整车、冷链),每种模式的计价规则完全不同。此外,客户要求与3家第三方物流系统对接(通过API),并且单据状态要实时同步。
单体应用开始暴露问题:订单模块的代码膨胀到4000行,一个if-else分支超过20层。我意识到必须重构。
我们做了两个关键决策:
- 引入策略模式处理计价规则:每种运输模式写一个策略类,通过工厂方法动态加载。代码行数从4000降到1500,新加模式只需新增一个类。
- 将对接模块独立为微服务:用Spring Cloud Gateway做统一入口,对接API单独部署。这样即使第三方接口不稳定,也不影响核心订单流程。
核心洞见:不要过早微服务,但也不要死守单体。当模块的变更频率和独立性出现差异时,拆分是必然的。
重构花了3周,期间客户催得很紧。我每天和客户开15分钟站会,同步进度和风险。最终上线后,订单处理速度从平均3秒降到0.8秒。
3. 后期:上线运维与数据教训
第五个月系统上线,前两周运行平稳。但第三周开始,每天凌晨2点数据库CPU飙升到100%,持续10分钟后自动恢复。排查发现,是客户的一个报表任务(统计上月订单量)在凌晨触发,扫描了全表数据,而订单表已经有80万条记录。
解决方案很简单:给报表查询加上时间索引,并把统计任务改为离线计算,结果存入Redis。但教训是:我们前期没有做完整的数据量级压测,以为80万条是小数据。实际上,客户的订单量在三个月内从日500单涨到了2000单,数据增长远超预期。
另外,日志系统一开始用Logback写本地文件,排查问题时必须登录服务器。后来紧急上了ELK(Elasticsearch + Logstash + Kibana),日志采集延迟控制在5秒内,问题定位效率提升80%。
4. 经验总结:五条铁律
- 需求确认要量化:不要只听客户说“支持5年增长”,要问“日均订单量预期多少?峰值多少?数据量多久到100万?” 然后做对应的容量规划。
- 技术选型看团队:6个人不要上微服务,但要有拆分预案。我选择Spring Boot + 策略模式,就是为后续拆分留接口。
- 变更管理要透明:需求变更不可避免,但要让客户看到代价。我每次变更都给出工期、质量和成本的影响,客户反而更理性。
- 压测要早做:上线前至少做一次200万数据量的压测,覆盖核心接口和批量任务。我们就是吃了这个亏。
- 日志和监控不能省:ELK、Prometheus、Grafana,这些工具在项目初期就应搭建好,不要等到线上出问题才补。
项目最终在第六个月准时交付,客户续签了第二期。复盘下来,最大的感受是:技术问题往往不是最难解决的,最难的是在不确定性中做出决策并坚持执行。如果你也在做SaaS项目,希望我的经历能帮你少踩几个坑。
最后,如果你需要类似项目的技术咨询或定制开发,可以关注我们公司的公众号「铭锦数智」,我们会定期分享实战案例。