野蛮生长 - 做支付的这一年
前言
如果,回过头来看看这一年走过的路?
留下的缘
玩支付这块的游戏得从大学开始。在学校呢,偶尔会做作业,而每次我选的课题都是与订单支付相关,比如,在线点餐、网上商城等,所以在订单这块玩的还挺溜。不过,个人账号申请不了支付相关的信息,需要相关的营业执照,所以每次演示项目效果都是简单的模拟支付结果,然后支付成功,评价…
两年前,我以实习生的身份入职这家公司,很意外的接触了公司的支付项目,然后,支付之旅就开始了。公司的支付系统从0到1,再到多个版本的迭代,然后进化成现在的统一支付平台,这一路还是有那么几个难忘的夜晚以及小故事。
被迫成长
19年的春节是在2月5号,以学生的名义在家度过最后一个元宵节,然后匆忙到公司,写代码,完善服务。第一次项目上线是在2019年3月12号,服务一发就是两天,从12号发到13号凌晨一点多,那天应该是我实习那么久来,成长最多的一天(但这次,却不是我最后一次,因为服务归档没做好而导致发布意外多)。我相信,很多刚走出校门的人,对于关键日志的打印,异常堆栈的捕获等,都欠缺完善的处理。而我,就是其中一个。当时服务上线后,移动客户端初始化请求一直报错,日志不详细,我不知道哪里空指针了,哪个数据库字段缺失了?怎么办?当时的解决方案就是加日志、重写发布,再加日志、重写发布,远程断点… 那晚,我感到十分的内疚和自责,为什么那么多的前期工作没做好?我还拖着我的领导到凌晨一点。其实,发布的问题他可以很快的帮我解决,但他没有这样做,而是一步步的指引我,让我冷静去分析问题,再去解决问题。
有问题不可怕,只要敢于面对,最终不都得以解决嘛。
业务发展谈不上飞速,却在7、8月爆发,也就是我刚毕业的那一两个月。最糟的情况下,我一周四天没写过代码,每天都在排查、追踪各种问题,那段时间压力很大,所有的问题都需要一个人抗住。现在回过头来,真是被迫生长啊。
支付的链路比较长,日志排查成了痛点,日志上下文杂多,分布式项目只能靠订单号定位关键日志,却丢失上下文。怎么办?日志链路追踪,在了解了相关开源解决方案后,选择了蚂蚁的SOFATracer (https://www.sofastack.tech/projects/sofa-tracer/overview/) 作为学习目标,快速简单的实现了一个内部版本,问题排查的难点解决了(已开源一个简单实现,开箱即用 https://github.com/0x4096/tracer/ )。至于为什么不直接用别人的工具,主要还是暂时没必要去使用这么一个较复杂的工具。
9月,支付项目有新需求需要上线,很幸运的是,那群同事刚好出现,替我分担了很多压力,否则我一个人,真的是做不完啊。而这个月也是我压力最大的一个月,我记得那天周四,我想去打个羽毛球,打了没20分钟,我就打车回公司了,我的心完全被束缚了。
经历了一个月的服务改动,四个人的代码增加、修改,项目上线的前提必须保证测试到位,服务完整归档。而那一天,服务发到凌晨三点,服务归档不详细,封版的代码还在改,MQ网络不通…,导致上线后出现一系列问题,哪能怎么办啊?我是主要负责人,所有问题都应由我一人承担…
从经历过这次以后,后面发服务都是沉稳…
加过的班
连续三个月的加班,周末,你要问我成长了什么?我不知道该怎么回答…但我还挺怀恋那段时间…
踩过的坑
- dubbo版本替换成Apache的,重试机制默认是2,由于网络问题,导致支付失败,重试出现问题…
- 订单查询核心参数没校验,导致支付错单号…
- 支付金额代码用double,导致精度丢失…
- 退款dubbo接口超时(其实已经成功),订单状态没改…
- 订单关闭,但是用户又支付…
项目进化
支付作为一个基础服务,主要提供便捷的支付能力供业务系统使用,整个支付链路如下图

公司的支付较为复杂,涉及好几个支付账号,同时又涉及多个支付场景,比如一家医院有多个支付宝账号授权,这时就需要配置使用哪个支付账号发起,那种业务场景操作。支付中心都屏蔽了这些细节,业务系统在使用接口时只需要关心核心参数即可,其他交付由支付中心处理。
支付涉及多个系统,将其拆分为支付中心,订单中心,通知中心,几个核心模块,业务系统接入支付能力,整体链路如下

一般支付系统都会进行拆分订单中心和支付中心两个系统。在最初的设计上,订单系统只提供订单相关能力,支付中心支提供支付能力,当时的业务系统需要接入支付能力,成本非常高,需要在订单系统创建订单相关,然后去支付中心获取支付能力,在支付完成后需要调用订单系统修改订单状态,这一做法对业务系统来说,太繁琐了。同时,在业务系统创建订单后,能不能简化支付呢?在支付中心我们封装的接口都是最原始的接口,如果让业务系统去直接调用,那么成本还是比较高,字段多,场景丰富。其实,对于业务系统来说,他只关心使用哪种支付渠道支付哪笔订单即可。所以呢,我们在订单系统封装了一套支付能力,简化业务系统的操作,同时可以控制订单信息,避免关闭的订单业务系统还能支付等。为了防止网络问题,导致接口超时,订单系统与支付中心的核心交易接口增加了交易结果补偿,避免出现单边账。
支付架构经过多次迭代,最终演变成如下图(参考了马蜂窝支付)

各模块各尽其责,职责单一。支付发展到今天,功能逐步完善,对账平台出现,聚合支付能力也跟上。
支付链路有多复杂?
我们在使用微信或支付宝付款之后,究竟发生了什么?来看个视频,微博原文 https://weibo.com/tv/show/1034:4523725815742474?from=old_pc_videoshow
总结
系统
- 日志,十分重要(包括规范),dubbo接口请求入参必须要,链路追踪不可少;
- 监控,出现异常,必须第一时间通知相关人员,尽可能的减少单边账,支付不可用问题;
- 异步,能走异步通过消息处理的,一律异步处理,减低系统耦合性;
能力
很幸运有机会去接触支付相关,领导的信任让我去负责这么一个事情,实现了公司支付系统从0到1的过程。这个过程,不仅仅是代码能力的提升…