背景
前端有个建站系统,运营可以通过拖动组件的方式搭建出一个落地页,大体流程为:
建站后台拖动组件搭建落地页 -> 页面搭建完成提交组件配置到服务端 -> H5带上url中落地页id向后端请求组件列表和组件配置 -> H5解析组件列表&配置渲染页面
这套流程在实际使用中存在一个问题:如果组件内部的配置发生了变更(比如弹层popup组件增加了弹层关闭自动唤起表单的配置项),如果不进到建站后台重新编辑保存落地页是无法将变更的组件配置生效到落地页中的。因此在制定团队技术目标时计划对这块进行优化。
优化方案
优化上述问题的逻辑非常简单:对一个组件的新旧配置进行同步。
如果旧配置中有的配置项而新配置中没有,说明是不再被使用到,则直接删除;
如果新配置中有的配置项而旧配置中没有则保留;
如果新旧配置中都存在的配置项则把旧配置项的值同步到新配置项中。
问题出现
在优化发布半个月之后,运营突然反馈有个落地页提交的表单信息中有个重要字段丢失了,影响到了一家消耗比较大的广告主投放广告。
于是立马排查问题,到建站后台查看该落地页配置时发现表单组件确实缺失了那个字段。先手动添加上该字段让落地页能继续正常投放。
之后排查代码问题,发现是在做配置同步的时候把旧配置中的表单项数据搞丢了。具体原因是表单组件有4个默认的表单项(姓名,手机号,省市区,具体地址),运营在配置的时候可以手动添加额外的表单项(如性别,年龄等)。
而按照优化方案中的规则,假如老配置中表单项有姓名、手机号、省市区、具体地址、性别,新配置中表单项只有默认的前四项,那么多出来的那一项就会被删除了。这就导致了问题的发生。
反思
这一项是写这篇文章的主要原因。因为第一次经历这么严重的生产故障(两小时产生了两万五的资损),要是啥也不记录就等于花钱连教训也吃不上了。同时这也让我的编码工作变得保守了好多 😥,之前看到一些可优化可不优化的老代码都会顺手给优化了,现在会顾忌优化工作带来的一些不可控的影响导致自己背锅。
列出一些本次故障的教训吧:
- 使用低风险方案代替高风险方案
这点是本次故障最大的一个教训,因为这次的优化工作是对整个系统的改动,属于风险特别高还不可控的优化工作;这种情况下其实是不太适合开发直接去对现有的代码/逻辑做修改的,反而可以使用低风险的增量方案比如增加组件提示等方式来提示运营人员注意组件的变动。
- 在改动点/风险点未完全评估出来之前不进入开发
这点是我犯了一个冒失的错误:激进地认为不把问题优化了发布上去那么问题永远也不会得到解决。但实际上对于系统来说,特别是老系统、访问量特别大的老系统,稳定运行才是第一要务。充满槽点却稳定运行的系统是要好于轻快运行却不知道什么时候会踩到坑的系统的。
- 增量代码风险远远小于重构代码
这是必然的,增量的代码改动点和风险点都更为明确。而重构代码就面临着与老逻辑冲突/丢失业务逻辑的风险。
- 工作的哲学:问题不出在我身上就不是我的问题
这话说起来可能有点不负责任,但对于一个上古流传下来的系统,重构的难度和开发量都太大了。老代码出问题可以甩锅给之前的人,但重构代码出问题只能自己背下黑锅。因此更好的做法是尽可能在一堆屎上再架设一层坚固的地基来承载之后的需求和逻辑。