警钟长鸣~01之19年一次记录

关于 6.14 日晚上上线客户价值的总结

上线内容

  • 客户价值定时任务
  • hotel-manger (门店后台)

涉及模块

工程

  • pig-yd-service

数据库

添加字段,后面字段没有被使用,已废弃该字段,但是没有及时从数据库中删除

其他开发

  • hotel-manager (门店后台)

上线前的准备

  • 数据库脚本

  • 合并代码(未及时合并到 master)

    当时没有使用 git-flow 这种工作流的试试,将 master 分支合并到开发分支,然后用开发分支打包上线。

上线过程

打包

  • git 合并

非常不顺利

事故原因

  • 执行初始化方法第一次 404 。原因是没有将代码合并到 master 分支,重新合并分支并上线。

  • 执行初始化接口第二次失败,原因是有一条异常数据。

  • docker 上没有日志,没有将日志打印到控制台上

  • 执行任务中途报错,有两个字段在测试环境中添加的后来废弃不使用了,生产环境数据库中没有这两个字段, SQL 执行报错。修改代码,从 Mybatis 配置文件和 Entity 对象中删除这两个字段的映射

  • 执行任务中途报错,数据库中有 meal_type_name 数据异常,值为午餐但是后面有很多空格,整个字段长度超过新建表中定义的长度。

    在代码中取该字段值的地方加上 trim() 方法

  • 打开门店后台页面,有一个接口报错,原因是有两个字段在测试环境下添加废弃后未删除,被映射进了 Mybatis 的 xml 和 Entity 对象中,查询时报 Unknown cloumn 'MAN_VIP_ID' xxx

  • 定时调度的任务不执行,原因是代码中的逻辑错误,导致 if 永远都为 false

    1
    2
    3
    4
    5
    6
    LocalTime startTime1 = LocalTime.of(23, 0, 0);
    LocalTime startTime2 = LocalTime.of(8, 0, 0);
    LocalTime nowTime = LocalTime.now();
    if (nowTime.isAfter(startTime1) && nowTime.isBefore(startTime2)) {
    xxxx
    }

总结分析

开发阶段

  • 开发阶段需求不够明确,基本都是似是而非。重述时,不能完成的讲出来每个字段的取值逻辑,只是能够听懂。
    • 规避,开会说明需求后,还要自己再仔细过一遍,对于每个计算字段是如何由来的,必须做到自己能够讲清楚,对于涉及到的表,必须要知道。
  • 开发前,对异常状态考虑不够周全,写出的代码健壮性不够。
    • 对所有数据都要认为不可靠,包含输入的和数据库中查到的,必须进行一次校验
    • 考虑到如果系统发生故障,再重新恢复后的情况
    • 如果是定时任务,任务本身要可控,可停,可启
    • 要做幂等,如果是定时任务,同一个任务,多次执行结果应该是一样
    • 代码执行过程要有日志,可以看到执行的痕迹,并且执行出错后可恢复
    • 代码执行的最大时间要可控,不能出现超长执行,定时任务,一家酒店的数据执行时间长达 30 分钟是不正确的。
    • 数据库查询,要考虑到上游的数据会持续增长,单次的查询量要固定或者控制在一个阈值之内,量大的时候多次去查询
    • 插入数据,数据库数据可观察,避免出现大事务提交的情况
    • 尽可能使用多线程处理,以提高性能
  • 业务理解
    • 充分理解需求,能够说清楚需求中每项数据的来源和流向,同时也能向别人讲述清楚,反复同产品确认
    • 清楚受众,功能提供给谁,在什么场景下使用
    • 对其他模块/系统是否存在影响
      • 现有表结构有无修改字段名称、类型、长度等
      • 现有表是否有删除/添加字段
      • 如果是新建表,表中数据是否要与其他现有表数据同步变动
      • 数据库中数据的来源是否有多处,其他模块/系统需要增加插入到新库的代码
      • 新建表中数据增加,是否需要往其他表中插入数据
    • 保持质疑,如果觉得某个做法有不合理,及时提出
  • 编码
    • 使用合适的数据类型, Entity 中不使用基本类型
    • 对数据所有的来源都认为不可靠,需要做判断
      • 代码要做健壮性判断,宁可多写 if (xxx != null)
      • 字符串考虑空格的问题,要去除前后空格
      • 判断的逻辑,测试时,要把 truefalse 都覆盖到,不能只测单个可能
      • 边界值,在做除法操作时,除数不能为 0,乘法时也要考虑 * 0 的情况
      • 有浮点数(小数)时,要考虑到精度问题,以及取舍方式。

在 2021-10-11 无意中再翻到的,发现之前记的一些东西现在做得也并不是那么好。