程序员应该怎样应对“扯皮”
今天帮一位同事处理一个工单,是上游(订单部门)的同事转过来的。说是客户的操作抛异常回滚了,抛异常的位置发生在支付系统(我们负责)。整个流程如下图所示。
简单介绍一下各系统的业务:
订单系统,在购物网站上把东西加入购物车的操作。
账单系统,在付款前显示您都买了什么东西,分别多少钱,总共多少钱。
支付系统:客户点击“立即付款”后,调用支付宝来划钱。
报错的大概意思是:转账不能是负数。
订单部门把工单转给我们的理由是,报错是发生在支付系统里,所以理应由支付系统的人来处理工单。
工单里的内容贴了客户调用订单系统api的购物请求的json串,以及返回结果中的报错信息。
我看了一下报错内容,确实是我常见的验证失败信息,也能从我们的代码里找到相应的地方。但是对于客户购物请求里的json是半懂不懂。我不负责任上游业务,对于上游系统的API不是很熟悉。仅凭客户发的json body,是无法复现问题的。一是因为线上的数据已经回滚了,DB无从查起,log里也找不到有用的信息;二是本地搭建“订单系统”服务的成本太高(毕竟是另外一个部门的系统),导致无法在本地尝试重现问题。
这个时候,我们再从全局看一下这个问题。这是一个跨业务领域的工单,应该由多个领域合作完成,仅仅靠一个业务领域的知识是无法解决的。支付系统与上游的接口是1)已经生成的账单 2)支付账单的请求内容(账户余额支付多少钱,支付宝支付多少钱,优惠券减免多少钱等等)。而订单系统的同事只在工单里贴出了客户传给他们的request body,并没有提供他们调用支付系统时传入的账单以及请求参数。对于支付部门来讲,如果不知道传入的接口数据,根本无从着手。
于是,立即找到订单部门的同事,跟他要接口传入的数据。订单部门的同事说,数据回滚了,提供不了。
既然这样,那咱就要掰扯一下啦:
第一,界定责任。我们抛的异常是校验失败的错误,这说明你们传入的参数有问题。报错信息提示得很清楚,并不代表我们的程序出了问题。
第二,指出问题。你们提供的数据我们看不懂,也没法用来复现问题。不是我们不帮忙,是你们没有提供有用的信息。
第三,提出解决方案。上游同事可以拿着客户的输入参数,试着本地复现一下。如果需要我们,把你们得到的账单信息与请求参数提供给我们。
此刻,订单部门的同事表示没毛病。于是“皮球”被我顺利地踢了回去。
后来,订单部门的同事复现时得到了账单信息,我看了一下,发现账单生成有误。这就好办了,再把“球”踢给账单部门的同事,让他们排查吧。
复盘一下吧这次“扯皮”事件:
- 如果我接住了这个“烫手的山芋”,肯定要花费大量的时间去研究上游的业务来重现问题,最后发现问题是出在账单部门,那么我的时间基本上算是白费了。
- 如果直接把“球”踢回去却不给出解决方案的建议,那么上游的同事可能也会比较迷茫,还会说我推卸责任,甚至可能亮“板砖”。软件行业不同部门之间的互殴咱也不是没见过,这个行业绝对属于高危行业。
- 而给出了合理的建议之后,订单部门的同事只需在他的领域内提供出边界数据就OK了。有了边界数据,应该找谁来负责就柳暗花明了。大家谁都不越界,谁都不背锅。
虽然博主用了“扯皮”这个词,但是我们绝对不提倡在工作中互相推诿,不负责任。我们提倡的是“专业的人做专业的事”。合理的“扯皮”使各部门各司其职,反而能提高整个公司的工作效率。合理的“扯皮”,使自己部门的员工专注于自己的领域,也能提高自己部门的效率,使自己的员工免于陷入不必要的工作内容,便于项目经理控制项目范围。
最后,我们来总结一下。
- 遇到责任不明确的跨业务领域的“扯皮”,关键要明确边界(接口)数据。如果没有边界(接口)数据,应该本着上游负责制。上游找到证据可以“踢”给下游,如果没有证据,“下游”应该踢回去,以避免不必要的浪费时间。
- 系统设计时,对于接口数据(我调别人以及别人调我)可以视情况保存一下,以避免扯皮时没有证据。本例中订单部门之所以没保存,是因为情况不允许。