今年接手了一个新项目,不算vendor包,大概6W行代码,接的时候信心满满准备大干一场。结果半年内线上出了100多个bug。
粗糙统计下,80%的代码是原来直接留下的,剩下的基本都是一脸懵逼地踩坑。其中也有不少是之前都知道,但是没处理掉,甚至还有查不到原因最后不了了之的。
流程与业务规则隔离
其实在上一家公司工作时就已经意识到这个问题的严重性,尤其是业务流程和业务规则经常来回改。
业务流程通常是一段简单的过程,甚至都不包含太多的分支流程。
业务规则是指针对不同的数据,在各个环节里需要不同的处理。
最常见的处理方式就是无处不在的 ifelse,这种方式的问题在于,每次改规则都要从头改一大堆代码,改完了还可能会影响其它 case,要整体回归才可以。效率和稳定性都很差。
更好的办法是,在主流程上使用 interface 把业务流串下来,每种 case 各自实现接口,各自测试。
有个小地方要注意,在设计这个 interface 时,要注意接口隔离原则,否则可能会出现为了增加一个特殊的 case,导致其它实现也跟着改一通。
日志那么多,有多少能帮助你还原现场
每打一行日志,都想想什么时候用,怎么用。
横向耦合、纵向耦合如果同时出现,代码就废了
一脚一个雷。
该收的口子一定要收口
一段代码同时copy在多个流程里,维护起来丢三落四。
丑陋的封装优于复制粘贴。
聚合服务,千万不要关心别人的细节
尤其是多个依赖的细节还不一样,真是灾难
双写幂等性,可修复性
不要第一次双写失败,导致后面数据都对不上。
出现不一致,一定要第一时间报警
避免阻塞性依赖
阻塞性依赖在流程管理中挺常见的,通常表现为在一系列操作中有几个操作依赖于不稳定的第三方。当中间一个环节出现不可控的故障时,会导致你的整个流程走不下去,然而因为是第三方出了问题,你只能干等着。
如果同时你的接口不具有全局的幂等性,这个问题还会造成非常恶心的数据不一致,处理起来也非常麻烦。
一个设计上的优化是把依赖第三方的环节后置。举个例子:
BBS 里用户发的消息要经过敏感词检查才能放出来,但如果你的敏感词接口挂了,可能导致全站不能发帖。一个可行的办法是,先发帖成功,再异步调用敏感词接口。有个问题是,在敏感词接口返回结果或恢复正常前的这段时间,贴子展示出来是否有风险?这个可以依据业务场景来处理,平时可以默认先放出来,敏感时期,那就让这个帖子只有自己可见,其它人等审核完成后才能看到。
成本会稍微高一些,但是系统健壮性会好很多。
字段命名一致性
数据结构上,不建议一个字段在不同场景下表示不同含义
大概出于省空间的目的,一个字段在不同 case 下表示了完全不一样的含义,时间长了。大家都懵逼了。
依赖服务的返回值,日志一定要清晰
善意的质疑,降低撕逼风险,这大概叫职业。
处理err时,一定要想想:如果这个error出来了,如何主动让我发现
api 错误后,如何快速定位哪一层抛的错
任何有业务含义的字段不能用来做pk
一改就疯
数据修改记录的重要性
最严重的有一张表没有创建和修改的时间戳,查数据问题时,都不知道从哪里开始查。