默认分支是个坑!

问题

  用户反馈了一个问题,业务系统将单据推送到OA后,找不到了,这是分布式系统中常有的故障,我们做了充足的准备,有状态监控,消息队列,主子系统日志,RPC等等,因为在这个应用需要推送超大附件,提交过程必须是异步的,但这次的问题,检查了所有的记录,日志,状态,没发现异常,业务系统记录正常,OA系统也没报错!耗费了好长时间,最后从OA接收后处理日志中找到些蛛丝马迹,经过反复重试,发现:当接收到特定数据后,OA调用了Save(暂存)方法,而不是正常情况下的Commit(提交审批),找到突破口,深挖下去,最后发现,当收到这种特殊数据时,OA判断不了下一步投送给谁来审批,于是就走了默认分支——暂存!在OA看来并不是异常。

背景

  为什么会这样,OA擅长做单据审批,定制复流程,但不适合做数据加工和计算,于是将业务拆分为业务和审批两部分,业务做数据创建、加工等,自主研发;审批由外采的OA系统来处理,当业务系统单据需要审批时,将推送到OA,OA审批后,将结果通知业务系统,业务系统得到通知后,根据token还原业务现场,继续相关业务逻辑处理。为了更好的用户体验,让业务系统完成审批流程的创建环节,即当业务系统提交到oa后,直接进入下一个审批环节,不需要用户再去OA上将单据提交一次。

分析

  设想很好,这次的问题就出在这里,由于数据比较复杂(多叉树型结构),加上流程判断条件繁琐,在写流程跳转规则时漏写了一个判断,导致oa无法得到下个环节的投送人,于是走了默认继承——暂存,这本是系统设计上要极力避免的,却出现了。

  解决这具体问题很简单,但如何有效的避免这类问题或出问题时能快速定位就比较难了,因为要解决好需要多多方面的协调:

  1. 多系统交互接口设计很重要,需要及时准确的给出状态反馈
  2. 边界测试很重要,特别注意默认分支,更要极力避免非白即黑的思考方式
  3. 数据模拟测试很重要,在正式运行之前先做模拟测试,对异常状态做分析
  4. 亡羊补牢很重要,但不能只是补上,更重要的是弄清楚为什么

结语

  是否相信存在完美的系统?不管你信不信,反正我不信,因为系统是人设计的,必然会有漏洞和疏漏,即使完全没有漏洞的系统(假设有)也对需求变化束手无策。只有勤于思考,保持足够的好奇心,对问题追查到底,才是长胜的法宝。