客观条件
参加工作多年,参与了许多项目,有新的,重构的,优化的; 有时是参与者,有时是负责人;总结下来有几点客观条件:
- 脏数据是不可避免的
- 数据库的迁移或升级是痛苦的
- 中间件的配置维护是痛苦的
- 系统性能还是需要考虑的
- 接口幂等香蓬蓬
对账方式处理脏数据 笨但简单直接
系统由多个服务组成,服务间彼此调用,很难做到事务; 某一环节失败,那么就有成功部分和失败部分的数据;失败部分是需要被处理掉的,否则随时间积累,未来某个时刻就会出问题;
对账系统就是将多方系统数据取出,然后按照业务约束,查询不满足约束条件的数据并清理掉; 属于主动型轮询式任务,需要评估查询数据对系统的影响,清理数据需要记录事件信息,可追溯问题; 对于系统内的脏数据可采状态机的方式处理,以状态轮转的方式处理,具有幂等性;
系统内收敛数据库操作
系统内收敛数据库操作的好处是数据库的升级或迁移改动少,稳定性高; 系统稳定性是业务的基础;
别看只是用API封装了一层数据库,但是给带来了众多好处;例如如下场景:
Q1: DBA通知由于数据库机器裁撤,需要更换数据库地址!
卧槽,没有办法,一个一个服务的改,有些核心服务,只能半夜改;尼玛,即没成就感,还伤身;
Q2: 团队人员流动太正常了,问一下那个数据库那个字段啥意思,有啥用?领导告诉你熟悉的同事已经离职了;😅 What Fuck!!
理解数据表设计以及字段的用途是有时间成本的, 数据表字段功能用途是需要时间积累;从数据库交换数据转变成接口交换数据,其一减少新人理解数据库表的时间成本;其二接口具有固定结构,交互方便;其三弱化存储组件的依赖,用着不合适可随时更换;
Q3: 业务增长快,性能不足;😄 堆机器 简单粗暴
数据库瓶颈头疼,加从库又将面对Q1;
以上两点太重要了,既省时间有提高效率
审阅代码的关注点
- 实现逻辑是否和业务逻辑匹配 基本要求
- 开发语言层面
- golang map 是否存在并发写入的场景
- golang chan 是否存在nil 写入的情况
- golang goroutine 数量是否收敛
- golang lock(mutex rwlock) 是否死锁 已经是否能够起到保护作用
- 接口幂等和非幂等,主要考虑是否可重复;大多数脏数据来自接口的不可重复性
服务命名简单点
- firewall api fwapi
- firewall ops fwops
服务或项目命名简单点, 越复杂越不好理解; 代码仓库利用好issue, 将代码commit 和 issue 进行发布关联; 提交代码 commit 前 git reset 方便审核同事阅读;
数据改动注意点
对于数据处理方式发生变化时(比如系统重构新老数据存储结构不一,需要数据同步), 注意存量数据和增量数据的问题; 注意由同步诱发数据一致性的问题, 读写操作的灰度控制;注意同步时数据量级问题, 是否需要限速处理; 容错性,即发生数据不一致时 对业务的影响程度和影响范围,提前风险评估;
API
请求参数 设置成 接口 可能会更好, 因为随着业务的增长, 某个请求的请求参数在不停的扩展,导致成一个非常大的结构体, 非常难拆解,最后该块代码无人知晓,难以维护; 接口隔离性的好处在于 每个请求接受结构不是固定的,但是满足某种业务功能;