前言
项目研发的过程中经历了需求评审、开发评审、代码编写、测试用例评审、项目测试、产品和UI验收等一系列流程,其中投入了大量的人力和精力。
然而最后的上线阶段,总是存在诸多不确定性和可变性,往往在测试阶段测N次都没有丝毫问题,一上线就会出现Bug(简直是墨菲定律的诅咒)。
经过多年的经验总结和残酷教训,我们将这些已知的或潜在的风险点详细梳理出来,希望每个项目的上线都可以踏踏实实、万无一失、顺顺利利。
本文,我们将从三个方面来防范上线风险:操作防范、双岗&自查、监控告警。
一、操作防范
主要包含了四大类别的防范:研发防范、配置防范、运维防范和审批防范。
1.1研发防范
1.1.1 通用层
Loading/Confirm统一标准化
错误页/骨架屏/无数据/网络异常兜底规范
公告、弹窗规范
1.1.2 代码层
使用https、禁止非jd源、验证外网可用
环境切换通过系统变量区分
Commit规范
▪ 单次提交独立功能代码
▪ 所有研发代码提交Coding
统一IDE和脚手架
开发环境node.js、npm、joyer、taro等版本统一
统一通用组件
▪ 沉浸式导航
▪ 共用组件,检测版本支持及容错处理
▪ 云梯组件
▪ 加密防刷:AKS,AAR
▪ 风控设备指纹
▪ 奇点埋点
▪ 下载唤起组件
▪ 分享组件以及金口令
- 数据处理
▪ 分页加载避免请求死循环
▪ 网关层错误码处理
▪ 服务端接口层错误码处理
▪ 主功能接口异常是跳转错误页/弹窗重试等必要处理
▪ 兜底方案
1.1.3 UI层
是否有动效
音视频是否兼容性
是否存在性能卡顿
1.1.4 安全层
编码问题:是否通过eslint
兼容问题:编码语法、方法属性、组件库最低支持版本等处理
逻辑功能:代码逻辑是否与预期功能一致
异常情况:是否考虑降级/容错/超时等异常情况
用户体验:新增或者修改功能对性能或者体验是否不良用户体验影响
安全:密文传输、防刷、脚本注入等
mock:是否正确处理了mock数据的展示
敏感数据:对数据处理是否存在潜在客诉风险等
1.2 配置防范
1.2.1 研发配置
内容配置平台配置已上线的配置再次操作要注意不影响线上,尽量新增配置
配置数据类型不支持时间控件,禁止在上面配置时间或时间戳等数据
配置前的数据校验(例如:链接格式是否正确,数据长度是否需要限制等)
数据容错处理,若为重要数据需设置为必填项 "required": true;
1.2.2 运营配置
活动上线前,所有生产配置必须都完成
已上线的配置,再次操作需与产品及研发确认;运营内部双岗确认
预发环境验证,数据和生产保持一致(奖品类型、券类型、秒杀时间、任务类型等)
奖励、券或任务等需验证可正常发放或领取后再配置展示到前端
在活动领取利益点到其他活动页使用,需保证二级活动页面内使用利益点正常
1.2.3 环境配置
所有新项目统一使用joyer脚手架初始化
命令统一,本地环境、打包、发布各环境等
vconsole、注释等仅在非生产包中配置
每个项目必须有mock环境,使用mock数据去验证各类情况,而不是修改或注释代码
老项目是否采用webpack、vue-cli统一规范
1.3 运维防范
1.3.1 域名解析操作
ip是不在应用下存在
实例上是否具有可访问项目
找运维配合查看是否项目可访问
确保告知运维工单受理通知开发人员及时验证
1.3.2 CDN操作
确保源站域名和加速域名不一致
确保上传的加速内容与分发方式相匹配(图片、大文件、视频、直播流)
确保加速域名下的文件为静态资源(考虑是否需要做动静分离)
确保源站IP是否正确
申请接入后只代表CDN已完成后还注意需配置DNS解析变更
查询输入域名查看全国各地区解析是否生效
1.3.3 HSTS操作
确保客户端或应用是否https或开启https强跳是否有问题
对于vip下有多个应用或域名要通知各方确认是否有影响
1.3.4 http2操作
确保域名为https才可开启
1.3.5 ddos操作
CDN域名暂不用接入
1.3.6 扩容操作
机器审批完成确认执行结果全部成功
确保新扩容机器配置及项目部署
对于混合部署有多个应用存在需要所有应用都完成部署并验证(可让运维配合)
混合部署应用确保每个应用都要走复用工单
确保扩容操作完成后重启机器操作
1.3.7 缩容操作
确保CDN域名解析的为内网VIP(如果为rip需要走变更VIP工单流程)
混合部署确保每个应用都要走工单
预发机器需要补充预发域名反向代理变更工单
1.3.8 下线操作
确保下线机器是否影响线上(独立部署某个项目)
注意摘流量-摘机器等步骤完成才可下线
1.3.9 回滚操作
使用JDOS点击回滚操作
回滚选择的包要仔细检查是否是上次上线的
1.3.10 堡垒机操作
容器必须正常启动
dockerfile构建的镜像,只能申请root权限且22端口必须打开
公共镜像,只能申请root权限且22端口必须打开
1.4 审批防范
是否经过测试节点审批
是否由leader审核
开发与审批权限是否分开
二、双岗&自查
上线前的双岗自查,是我们制定的一项标准流程。要求研发人员在上线前必须按照下面的清单,并寻求其他同事的协助进行项目代码的排查(当局者迷,旁观者清)。
2.1 前端
2.1.1 环境检查
域名是否接入CDN
jen配置是否一致
jen是否全部在线
是否开启gzip
部署机器数量与预期是否一致
2.1.2 公用组件
是否接入AAR
是否接入AKS
是否接入风控
是否添加SGM监控
2.1.3 需求检查
本次上线资源是否包含非本次产品需求迭代内容
页面引入资源是否都是本次上线内容
本次上线资源是否为预发已测试版本
2.1.4 代码检查
是否有第三方代码注入
是否存在敏感字段
是否去掉log/mock/Vconsole等调试工具
项目中是否存在http域名资源
服务端接口是否为线上
检测所有资源域名是否为线上外网域名
包资源文件hash是否由生产部署
仓库master代码是否是最新的
对于混合部署应用,本次上线是否只更新当前应用代码
对于通天塔自定义组件,本次改动是否考虑低版本,是否影响其他项目中引用的模板
2.1.5 回归检查
使用4G/5G验证
上线后操作CDN资源是否是最新上线的
上线后验证。对于混合部署的项目,最新分支是否合并到master
2.1.6 流程工单
双岗检查确认通过
UI走查通过并确认
风控验收通过并确认
安全测试工单提交并完成
2.2 服务端
2.2.1 监控检查点
- 业务监控
◦ 订单
◦ 日志异常
◦ SQL异常
◦ SQL耗时
◦ 业务耗时监控
◦ 业务状态异常监控
◦ 异常流程监控
- 基础监控
◦ 第一类运维:应用系统所依赖的硬件、虚拟机、网络等
◦ 第二类运维:操作系统层面,比如cpu,内存,硬盘,IO等
◦ 第三类运维:中间件层面的,比如数据库,缓存,tomcat, ningx等
◦ 第四类运维:应用本身的,比如JVM监控, 日志归集等
◦ 第五类运维:新功能上线操作和日常应急演练工
2.2.2 通用自查点
- 上线顺序类
◦ 内部存在多个应用上线,依赖关系及上线顺序,是否已经考虑过
◦ 应用上线前,是否需先创建好了相关表结构,注册mq,rpc等操作
◦ 本次版本上线,是否涉及外部应用,是否需要别的模块配合,上线是否有顺序要求
- 安全类
◦ 是否要考虑外网安全问题,比如SQL注入,XSS攻击,敏感信息加密,账号爆破等
◦ 是否考虑接口通信安全问题,加签验签,秘钥管理等
◦ 各种访问是否考虑要增加白名单或者证书或者短信
◦ 数据库敏感字段是否加密
- 防刷,防重类
◦ 防重机制,哪几种状态和场景下允许重复发送订单
◦ 否有限制允许同一秒接受多笔同样的订单
◦ 平台唯一ID生成是否会有重复的可能
◦ 所有请求入口,定时器和API请求是否使用乐观锁。考虑并发重复处理问题,并且要判断更新影响条数
- 异常处理类
◦ 是否处理了各业务的主分支以外的异常分支
◦ 详细异常栈别吃掉
◦ 三方交互的是否完成
▪ 需要抓取IOException做处理
▪ IOException需要打印URL方便报警排查问题
▪ 需要设置连接超时和读取超时时间
▪ 是否需要通过代理出网
▪ 是否需要再三方添加白名单
▪ 三方是否有最大数限制
▪ 合理设置http连接数和关闭连接
- 日志规范类
◦ 日志打印是否有自己的业务规范,有助于日志巡检
- 定时任务类
◦ 业务定时器是否有浪打浪,重复处理的情况,并发配置是否设置成false
◦ 定时任务中处理的数据量是否有预期的执行size,是否会出现异常情况下,处理的size越来越多的情况
- SQL类
◦ 是否使用了唯一索引
◦ 唯一索引的使用是否正确,例如多个字段做为联合唯一索引,是否存在字段为null情况
◦ update和select语句是否有预期的执行size
◦ 是否避免使用复杂sql
◦ sql是否检查过执行计划,是否能命中索引,一段时间业务增长是否存在慢sql的可能性
- 缓存的使用
◦ 缓存使用,是否设置超时时间,超时时间设置是否正确,是秒单位,还是毫秒单位
◦ 缓存同步问题解决方案的评估(数据库悲观锁+事物+排序、redis悲观锁、CAS)
◦ 清楚redis的使用场景
- 事务的使用
◦ 代码中使用事务的需要考虑死锁场景
- 管理后台
◦ 管理后台下载,查询等功能是否有条数限制和频次限制
- 类型转换
◦ 类型转换是否正确,是否先判空再进行转化
- 连接数,线程数
◦ 线程的创建是合理地否限制了线程数量
◦ 相关中间件的连接池数量设置是否合理
- 返回码解析
◦ 解析响应码是否正确,特别是对于网络异常、catch异常、无此订单等特殊情况
◦ 响应吗解析-网络异常/订单不存在(网络异常导致和查询早于交易导致),非明确失败,不可以设置失败
- 系统设计问题
◦ 异步转同步,如果后端异步部分组件宕机或重启,导致同步dispatch数据一致被阻塞
◦ 是否存在单节点
◦ 是否要支持分布式部署
◦ 乐观锁防止并发修改,悲观锁
- 超时时间设置
◦ 任何RPC调用地方是否设置连接超时和响应超时时间,包括HTTP、redis、数据库等
- 金融属性
◦ 记账类功能需要考虑余额和流失是否在并发情况下准确
◦ 金额单位,精度是否正确
◦ 金额类型转换是否正确
- 时间写法
◦ 时间格式,精度是否有问题,是否会出现写库后四舍五入的情况,导致查询不匹配
◦ 数据库时间配置问题,是否设置东八区,活动是否对时间使用东八区格式
- 配置文件
◦ 线上配置文件是否单独抽离上线包,是否已提前在平台单独配置
◦ 若存在不抽离的配置文件,随代码提交的配置文件,是否已检查是正式环境的配置信息
2.2.3 资源支持项
是否要运营提供额外支持,比如运营后台参数配置等事项
是否要运维提供额外支持,比如配置网络环境、添加证书秘钥、创建文件目录、添加和删除jar包等事项
是否要DBA提供额外支持,比如新增模块添加数据库访问白名单等事项
三、监控告警
监控告警是上线后的风险治理必要机制,一旦出现告警,我们可以第一时间排查和解决,防止更多的客诉产生。
- RPC层监控
◦ 超时监控
◦ 异常报错
◦ 可用率
- CACHE监控
◦ redis连接异常
◦ r2m可用率
◦ r2m容量
◦ r2m主从切换
- MQ监控
◦ MQ接收重复
◦ MQ发送失败
◦ MQ内处理失败
- Task监控
◦ 定时任务未执行
◦ 定时任务超时
◦ 定时任务执行异常
- 业务异常监控
◦ 获取锁异常
◦ AKS和防刷未通过异常
◦ 任务领奖/接取等异常
◦ 人群没有权限
- JVM监控
◦ fullGc日志与告警
◦ jvm监控告警
- 容器监控
◦ 实例存活
◦ CPU负载&使用率
◦ 机器内存
- DB监控
◦ DB层CRUD执行异常
◦ cleverBD慢SQL定期巡查
◦ DB查询操作时间超长
◦ 线上环境(应用、数据库、配置等)审批负责人是否为当前leader
- 利益点监控
◦ 营销发奖失败
◦ 库存不足
◦ 活动未开始/已结束
◦ 被风控
◦ 防重失败
◦ 单个用户领取利益数量超过配置的警戒线
◦ 活动整体发放量超过配置的警戒线
◦ 其他异常失败
- 业务响应码监控
◦ 第三方接口正常码和异常码配置来监控可用率
- 配置校验
◦ 获取配置异常
◦ 配置中该配应配字段未配置
◦ 配置中字段配置类型异常
◦ 没有符合当前时间的配置
◦ 活动已结束但仍然有大量用户访问
◦ 多个配置的时间点冲突
◦ 配置的奖励Id/任务Id等在第三方接口未查询到
◦ 每次运营修改配置,修改项通过告警发送到研发,对告警分等级
- 活动资格校验
◦ 绕开某个校验告警
◦ 应是老用户领奖但新用户通过前置校验进入领奖流程
作者:京东科技 胡骏
来源:京东云开发者社区 转载请注明来源