从踩坑到收获:一次高并发支付系统的架构探索与实战
引言:业务压力下的技术升级

2023年初,我所在的公司正处在高速发展阶段。我们负责的核心产品是一个面向中小商户的聚合支付系统,支持多种支付渠道、交易类型和复杂的分润逻辑。随着用户量的迅速增长,原有的单体架构逐渐显得捉襟见肘。
尤其在双十一、年中大促等高峰期,系统的处理能力频频“亮红灯”——接口响应变慢、偶发超时、数据库连接池耗尽……这些信号都在提醒我们:必须重构系统,才能支撑未来的业务增长。
于是,我和团队决定启动一次全面的技术升级和架构优化。这篇文章就记录了那次项目实践中的真实经历和思考,分享一下我们的技术选型之路、遇到的挑战以及最后取得的成果。
项目背景:一个典型支付平台的痛点

我们维护的系统最初是用Spring Boot搭建的一个典型的单体应用,所有功能模块(如订单管理、支付通道集成、对账系统)都部署在同一台服务器上,通过本地调用进行通信。数据库采用MySQL,Redis作为缓存层,整体结构清晰、开发速度快,非常适用于初期快速验证业务场景。
但到了业务爆发式增长阶段,问题就出来了:
- 吞吐量瓶颈:单实例QPS撑不住流量高峰,扩容不灵活。
- 代码耦合严重:模块之间依赖复杂,改一个小功能要牵一发动全身。
- 运维困难:发布一个版本需要整站重启,故障影响范围广。
- 伸缩性差:数据库连接池有限,经常出现卡顿甚至拒绝服务的情况。
我们当时的日均交易量大约在50万笔左右,促销期间最高突破120万笔/天。系统稳定性已经成为摆在我们面前的一道门槛。
遇到的挑战:多管齐下的复杂升级

我们在前期调研中设定了几个关键目标:
- 系统可用性达到99.95%以上;
- 支持弹性扩展,能应对突发流量;
- 提升支付成功率至98%以上;
- 降低核心链路延迟,提升用户体验。
看起来目标很明确,但在真正落地过程中,才发现事情远比想象复杂。
挑战一:如何优雅拆分单体服务?
我们最初的计划是微服务化。将原本的功能模块如订单服务、支付服务、对账服务等逐步拆解。但在拆分初期,我们低估了接口定义、调用链监控、配置中心、服务发现等问题的复杂度。
举个例子,最开始订单服务调用支付服务是本地方法调用,改为RPC后,出现了很多意想不到的问题:超时重试机制不合理导致幂等失败、请求堆积压垮下游系统、异常处理策略不统一……
后来我们采用了OpenFeign + Resilience4j组合方案,结合熔断降级、限流机制、异步消息补偿等手段,才逐步稳定住。
这里插个小故事:有一次上线之后,某个支付回调接口因为超时被熔断,结果大量待处理交易滞留在队列中。幸好有定时job兜底兜住了,不然第二天就会收到一堆投诉电话了。
挑战二:数据库架构扛不住高压读写?
随着微服务拆分完成,新的问题来了:数据库的压力更大了。
之前是“单体”,现在变成多个服务并发访问同一个库表,锁争抢更加频繁。特别是支付成功的回调事件密集涌入时,数据库CPU直接飙到95%以上,长事务频发。
为此,我们做了几项改造:
- 垂直拆分数据库,按业务域划分不同的库表;
- 推行读写分离,将报表类查询独立出去;
- 对部分热点数据使用Redis缓存,降低数据库负载;
- 使用ShardingSphere进行水平分片(虽然最后只分了一张流水表,但也带来不小的收益);
在这个过程中,我们也踩了不少坑,比如:
- Redis穿透导致缓存失效;
- 分表字段选择不当,引起数据分布不均;
- 分布式事务没有做好一致性保障,导致资金错乱。
最终我们还是靠引入Saga模式和异步补偿来解决分布式事务问题,并用TCC模式保证了部分关键支付操作的强一致性。
技术方案:以稳定为前提,构建可扩展架构
这次架构改造的整体思路是:“稳得住、扩得开、看得清”。
技术栈选型与权衡
在整个升级过程中,我们主要用了以下技术栈:
| 模块 | 技术选型 | 说明 |
|---|---|---|
| 微服务框架 | Spring Cloud Alibaba + OpenFeign | 兼容现有Spring生态,社区活跃 |
| 配置中心 | Nacos | 实现配置热更新,方便灰度发布 |
| 注册中心 | Nacos + Apache Dubbo | 微服务注册与发现 |
| 链路追踪 | SkyWalking | 替代了之前的Zipkin,性能更好 |
| 日志采集 | ELK + Filebeat | 集中式日志分析 |
| 缓存中间件 | Redis Cluster | 满足高并发读写需求 |
| 数据库分库分表 | ShardingSphere-JDBC + MyCat | 根据业务特点定制分片策略 |
| 异常熔断 | Resilience4j | 比Hystrix更轻量且支持Java8语法 |
值得一提的是,我们在是否选择Dubbo还是Spring Cloud做远程调用方面有过激烈讨论。最终考虑当前团队熟悉Spring Boot生态,加上Dubbo3已经原生支持Spring Boot,所以两者融合使用,各取所长。
解决过程:边走边看,持续迭代
整个项目历时5个月,分为三个阶段推进:
第一阶段:基础能力建设(第1~2个月)
搭建起微服务基础设施,包括网关、配置中心、注册中心、日志监控体系。这个阶段重点在于打好底子,虽然表面上看不到明显效果,但后续一切优化的前提都建立在这里。
小插曲:有一天下班前突然发现Nacos集群节点状态不一致,差点没上线当天的新版本。后面才知道是因为网络分区导致脑裂,好在及时恢复了。
第二阶段:核心链路微服务拆解(第3个月)
我们将订单、支付、风控三大核心模块进行服务化拆解。并同步完成了接口设计、熔断机制、幂等处理等工作。
这里最关键的一环是对“重复支付”的处理。由于前端多次点击或网络抖动,会出现同一个订单号多次提交的问题。我们采用Redis+UUID的机制,在进入支付流程前预校验,确保幂等性。
第三阶段:稳定性增强与性能优化(第4~5个月)
这个阶段我们主要做了以下工作:
- 数据库垂直拆分 + 读写分离
- 使用线程池隔离不同资源调用(防止雪崩)
- 对高频查询增加缓存
- 增加自动化预警系统(Prometheus + Grafana + Webhook)
尤其是引入了SkyWalking之后,我们可以实时看到各个接口的执行耗时、异常率、链路拓扑图。这大大提升了我们排查线上问题的能力。
效果总结:不仅仅是性能提升
经过这次升级后,系统表现有了明显的改善:
| 指标 | 升级前 | 升级后 |
|---|---|---|
| 平均TPS | 800次/秒 | 2600次/秒 |
| 支付成功率 | 93% | 98.5% |
| 主链路平均响应时间 | 180ms | 70ms |
| 系统可用性 | 99.2% | 99.95% |
| 新功能上线周期 | 2周 | 4天 |
更重要的是,整个团队在架构层面的认知有了显著提升。过去我们更多关注实现功能,而现在大家开始更多考虑系统的伸缩性、可观测性和可持续发展。
经验分享:给后来者的几点建议
如果你正在面对类似的系统重构或者性能优化需求,我希望我的经验可以帮你在路上少走点弯路:
1. 先搞清楚为什么做
很多时候我们以为“要做微服务”,其实只是为了解决单一维度的问题(比如性能、伸缩性)。但微服务带来的代价并不低,比如运维成本上升、跨服务调用复杂、一致性要求更高。
所以请先问自己:你到底想解决什么问题?有没有更轻量的解决方案?微服务是不是唯一的选择?
2. 从小切口切入,持续演进
我们最初也想着一口气拆掉整个系统,但后来发现不可控。最终采取的是“核心链路优先拆解,其他模块逐步跟上”的方式,效果更好。
不要试图一开始就追求完美架构,而是从能解决具体问题的地方入手。
3. 重视监控和日志体系建设
微服务时代,没有良好的观测能力,就像在黑暗中开车。推荐使用SkyWalking这样的APM工具,不仅能观察接口耗时,还能追踪整个调用链路,对排查问题帮助非常大。
4. 合理利用缓存,同时警惕副作用
缓存确实是提升性能的有效手段,但也要注意缓存击穿、穿透和更新不及时的问题。我们在一次活动上线时,忘记清理热点缓存,导致数据不一致,引发客户投诉,教训惨痛。
5. 别忽略人与团队的成长
架构升级从来不是一个人的事。我在项目中期特意组织过几次“技术复盘会”,让大家一起回顾踩过的坑、做的决策。这种形式不仅帮助新人成长,也让老成员重新审视自己的判断。
写在最后:技术的价值在于解决问题

写到这里,我想说,作为一个技术人员,最大的成就感不是写出多么酷炫的代码,而是用技术真真切切地解决了实际问题,推动了业务的发展。
每一次架构优化,都是对技术认知的再次打磨;每一次失败,都是成长的养料。而最重要的,是在不断实践中,找到属于自己的那一套“最佳实践”。
希望这篇来自一线的真实案例,能够对你有所启发。如果你也有类似的经验,欢迎留言交流,我们一起进步。

评论 0