前言
挺长时间没发文了,因为公司有一个紧急项目要赶进度,加班如吃饭喝水,久违的进入到码农的状态。
之所以抽空来发个文,是这个项目才刚上线,时间不长却因为一位新同事的代码引起了生产环境的事故,造成了一批短款,差点让整个团队这段时间的努力付诸东流。
所以,本着好人一生平安的处事原则,百忙之中我依然抽空以文章的形式把这次事故记录下来,希望有做支付相关功能的同行们能够引以为鉴。
经过
1、包装简历不是错
大家知道,每年到这个时候就是一个公司人员变动最频繁的时候,有些是拿了年终奖走人,有些人是骑驴看唱本,找到下家然后走人,反正这个时间就是传说中的金三银四。
如果公司这个时间有紧急项目,一定是你难受我难受大家一起难受的阶段,因此,为了应付这种情况,人事顶着很大压力招人,往往不一定能招到合适的。
我们公司年后就入职了一位新同事,就是专门为这个紧急项目招过来的,简历我有看过,3年工作经验,熟悉Java、SpringBoot、SpringCloud、SpringCloudAlibaba,还会docker、k8s,会前端vue、uniapp用法,有过微信小程序开发经验,且熟悉微信支付、支付宝支付开发。
其实,前面熟悉java、springboot、springcloud什么的,我们面试没遇到过不写的,基本上没当回事,而后面的docker、k8s也只是个添头,因为来公司没人会让开发同事来操作,会点前端的vue倒是加分项,最重要的是最后一句,熟悉微信支付、支付宝支付开发,这一点一下戳中了人事的软肋,因为主管特别给人事提过会支付功能的优先考虑,所以人事打电话了解后极力推荐给主管。
主管看后发给我看,我们其实心里都有数,这简历里面的项目一看就是包装过的,因为大家都这么过来的,写的3年经验,大部分其实只有1年或2年,偶尔能遇到没有经验但盲写3年的,对于中小公司而言,面试人员包装简历不是什么问题,重要的是能干活就行。
改天主管就喊我一起去给这位同事面试了,这人口条很好,我们问的很基本,都是挑他项目里写过的技术来问,基本上都能答出来主要的,主管心里也很满意,面试完后就给人事说让他入职了。
2、能干活不一定会干活
新同事来周周一入职的,经过了简单的培训,立马就要投入到紧急项目中,好在这是个新项目,不需要他额外熟悉既有的业务,产品评审过后就开始分配工作,因为人员变动导致的工作积压,我和另一位老同事手头上都有离职人员交接的工作,需要日常维护老项目,加上同时参与新项目开发,有些力不从心,主管考虑到这点,就把新项目微信支付相关的功能都交给了这名新同事,因为他简历中确实写了会这部分,而且面试时连我也觉得他明显是会的而且做过的,后面事实证明只是他口条好罢了……
从真正开始做项目,我就发现此人会的确实挺多,但问题更多,比如git工具只会pull和push,遇到代码冲突不知道如何解决,瞬间拉低了他原本通过面试在我心中塑造的等级。
再比如他很喜欢使用try..catch,每个接口都加,却不知道我们本身就统一了异常管理,更可怕的是catch中竟然写e.printStackTrace()这玩意也提交上去,我专门给他提醒后他才改成log.error("xxxx:{}", e.getMessage()),我当时看到也无语了,又跑去说你不要getMessage(),这样生产环境不好排查问题,改成log.error("xxxx:", e)就行,他当时反问我这样能打印出来东西?此时我心里已经蒙上了一片阴霾,也发觉到他对我三番四次跑去指点他似乎有些许不满。
工作忙起来后很多时候你不是领导,你也不太想管那么多,管好自己就行,我也懒得再管他了。后来证明我这种心态也是隐患之一,团队开发成果是由大家一起决定的,果不其然最后出事故连坐了,谁也逃不掉。
3、事故来的就像龙卷风
等到项目进入提测阶段,测试出来的BUG虽多,但总体不错,新同事负责的那部分之后也通过测试了,我当时觉得他其实还是挺有能力的,支付这块业务上还是有很多痛点的,他能自己一个人做完确实不容易,简历上虽然包装过可干活还是可以的。
项目上线后,大家都松了一口气,毕竟是个紧急项目,也牵扯到公司今年的战略规划,能完成对我们老同事来讲是一种解脱,对新同事来讲是一种自我价值的证明,3个月没到他提前顺利转正了。
那句话怎么讲来着,是福不是祸,是祸躲不过,今年属蛇的人据说犯太岁,这才刚开年,我果然间接中弹了,项目上线不到一个月,某天上午客户方突然出现大量短款,造成直接损失接近十万元,好在我们驻点人员较多,紧急情况也有备案,接到通知后马上关闭了开关,等到高峰期一过,才重新打开开关继续运行,否则很可能持续造成更大损失。
大家心都快跳出来了,好在接下来整个下午都很平静,没有再出现问题,我们根据经验立马判断是上午那段时间处于流量高峰期造成的。
排查日志后发现竟然是微信退款的回调中进行业务确认时大量失败,从而造成了大量短款。
至于分析和解决的过程,在后面分析小节中会说明,这里提一嘴,这名新同事知道问题是自己造成的后脸都白了,那会儿说话也不利索,还被其他同事埋怨了几句,样子别提多可怜了,看着让人心酸,事故处理完成后他自己就离职走人了。
我能感受到这次事故对他的整个程序员人生都是一次重大打击,临走前还专门找他说了些安慰的话之类的,把改正后的代码片段也发给他作为参考,我这人比较心软,见不得相处一段时间的同事那么难受,还把他推给了以前公司熟悉的人事,帮忙给他找新工作,我能做的也就这么多了。
最后客户方追回了损失大概六七万,还有两三万追不回来了,因为是短款,人家不退你也没办法,这还是在我们驻点人员响应及时的情况下,否则可能今年和这个客户的生意彻底要黄了,公司后来交代事故原因时也没有说是我们代码写的有问题,全部推给调用业务确认接口超时引起的,同时赔偿了没追回的金额,最主要是领导层关系很硬,这一劫算是度过了。
分析
前面讲了,排查日志后发现是微信退款成功后回调中进行业务确认时大量失败,从而造成了大量短款。那么很多小猿猴就很奇怪,我说的是什么意思。
这里就要提下微信支付等支付功能开发过程中的必要流程了:
支付:创建业务订单---> 创建支付订单---> 唤起支付收银台---> 输入密码或指纹支付---> 进入支付回调处理 ---> 更改支付状态及业务状态
退款:创建退款订单---> 发起退款---> 进入退款回调处理 ---> 更改支付状态及业务状态
主要的流程大概是这样,里面还有一些细节,这里针对本次事故着重说下回调处理这块,当一个支付完成后,微信会发给我们的回调接口进行最后的业务处理,正常来讲只需要更改我们自己的业务表状态就行。
但如果你的项目不是公司自有产品,而是给客户做的,牵扯到客户自己的业务系统,那么就很有可能需要在回调中专门去调用客户系统提供的业务确认接口,简单来讲,就是你要告诉客户系统这笔支付完成了或失败了好让业务系统做一些自己的逻辑处理。
我拿这次事故项目的业务为例,客户系统的支付环节有一个前提是从号源池中取号,而退款时要进行退号或销号。这里就不单单是一个微信支付的简单实现了,而是一个重要的业务逻辑实现。
大家可以思考下,我们到底是要先取号再支付还是先支付再取号,同样的,退款时我们是要先退款再退号,还是先退号再退款呢?
我相信,如果不是经常做支付相关业务的小伙伴,在没有经验的情况下一定会写错的,而这里就是我们这位新同事犯的问题:
在退款时,他的代码逻辑写的先退款再退号,在流量高峰期,因为try...catch中写了异常时自动退款,结果刚好发生了预料之外的异常,开始自动退款,好死不死的客户方业务系统也有问题,最终导致退款执行成功了,调用客户方业务系统退号确认接口时却确认失败了,结果就是钱先退给用户了,号却没退掉(人活着,钱没了),在客户的业务系统里这就是一笔短款。
究竟正常的逻辑是怎样的,我以这个案例给大家梳理下就清楚了:
1)、支付时,一定要先完成支付,再处理业务系统的业务。
比如这里就是先支付再取号,这样的好处就是,正常情况下没事,异常情况下要么支付失败就不走后续,要么支付成功但后续取号失败,这样你服务的客户方没损失,损失的是用户,因为用户已经付钱了,这就是一笔长款,客户方只需要根据用户反应的情况审查一下然后退款给用户就行了。
相反,如果你写反了,导致的其中一种后果就是用户先取了号,但支付失败了,用户依然可以拿着号来用,这对客户方就是一种损失,钱没收到号还能用。
2)、退款时,一定要先完成业务确认,再执行退款。
比如这里就是先退号,再退款,这样要么退号失败不会往下走,要么退号成功,但退款失败,损失的依然是用户的钱,客户方怎样都没损失,形成一笔长款,审查过后确认情况没问题再退款给用户即可。
相反,如果你写反了,导致的后果就是先退款,但退号确认失败了,客户方的号还没退回来,但钱已经打进用户账户了,客户方就损失了,还得找用户追回来,如果用户不给你也没办法,因为是你自己的失误导致的,这就形容严重事故了。
案例分析梳理的逻辑,不仅仅在这里适用,在其他场景也是适用的,大家可以多看看仔细揣摩下,任何和钱打交道的功能开发都要谨慎,支付功能实现一点都不难,有现成的工具可以使用,难的其实还是业务,遵循一个原则:不管你的业务逻辑怎么写,只要正常及异常情况下,你服务的客户都不会亏钱,那么你的支付逻辑就是正确的。
总结
现在新技术非常多,学起来累不说,还卷,我诚心给大家一点建议:
1)、减少对热门流行技术的病态追逐,沉下心来把基本功打扎实,进入公司后需要用到的开发工具、开发流程、代码规范等等多花点心思学习,因为你就算把分布式技术学的再厉害,这些盖房子用的工具不熟悉,会很容易被看破手脚;
2)、进入公司第一件事,熟悉业务场景,这往往才是你在公司往后的立身之本,工作时间越长你越会明白;
3)、简历不要过分包装,包装无可厚非,很多人都这么干,都是为了生活,但过分包装会带来隐患,比如这里讲的这个同事,专门把微信支付等功能作为亮点,结果缺乏真正的经验导致事故。
最好不要在简历中牵扯到支付相关的介绍,可以说参与过,但不能形成亮点,因为和钱有关的技能都不简单,多对简历中的项目进行润色更有效果。
纯手打,觉得有一滴滴帮助的话,麻烦点个推荐吧啦吧啦~~~~~~
也可以关注下我,本人专注分享工作中的趣事和实战经验哦~~~~~~~~
__EOF__