前端稳定性建设

时间:2022-09-19 09:39:36

  稳定性是数学或工程上的用语,判别一系统在有界的输入是否也产生有界的输出。若是,称系统为稳定;若否,则称系统为不稳定。

  前端的稳定性大致也可以如此概括,简单地说就是在外界影响下表现出的某种稳定状态,例如无报错、响应快、内容呈现正确等。

  要想达到稳定状态,需要做些有效的防范措施和机制,而这些也正是我们组现在和未来会持续推进的工作之一。

  线上业务是必须要监控的,否则在排查用户问题时将无从下手。

1)业务监控

  业务监控就是与业务相关的监控,常见的就是Node.js的代码日志。

  包括数据库查询语句、内部通信的请求和响应、自定义的打印、代码报错等。

  这部分在接入阿里云的服务后,就可以通过阿里云提供的日志网站查询到,如下所示。

content:
{
    "name": "koa",
    "pid": 26,
    "req_id": "4df3f997e7dc6c03eeaac3e1e01ee0f5",
    "level": 30,
    "msg": "  <-- POST /services/getKey",
    "time": "2022-08-23T10:25:21.927Z",
    "v": 0
}
content:
{
    "name": "backend",
    "pid": 26,
    "level": 20,
    "msg": "4df3f997e7dc6c03eeaac3e1e01ee0f5  SELECT `id`, `title` FROM `app_global` AS `AppGlobal` WHERE `AppGlobal`.`key` = 'xxxxx' LIMIT 1",
    "time": "2022-08-23T10:25:21.928Z",
    "v": 0
}

  其中第一条的req_id和第二条msg的第一段字符串是一个标识符,可将通信和其他日志串联起来,这样就能在几百万条日志中准确的查到,这次通信查了什么表、打印了什么内容等。

  还有一部分业务监控需要自己搭建,包括前端的脚本错误、异步通信、性能参数等。

  目前已研发出SDK,嵌入到线上各个H5网页,以及小程序。

  配套的管理后台也在稳定运行中,可实时查监控各个项目的异常,异步通信的JSON响应。

  虽然代码日志可以记录Ajax请求的地址,但是无法输出Ajax响应的JSON数据,如下所示。

  所以才又重新研发了一套前端监控系统,补充服务端日志的不足。

{
  "type": "GET",
  "url": "//web-api.xx.me/game/detail",
  "status": 200,
  "endBytes": "0.17KB",
  "header": {
    "req-id": "4df3f997e7dc6c03eeaac3e1e01ee0f5"
  },
  "interval": "195.7ms",
  "network": {
    "bandwidth": 0,
    "type": "4G"
  },
  "response": {
    "status": 1,
    "data": {
      "count": 3,
      "isExperience": true,
    }
  }
}

  注意,在日志中也有一个req-id字段,用于和服务端的代码日志做关联,便于排查。

  性能监控也是业务监控的一部分,主要监控着白屏、首屏、各个阶段的耗时等,如下所示,单位ms。

{
  "unloadEventTime": 0,
  "loadEventTime": 1,
  "interactiveTime": 580,
  "firstPaintStart": 771,
  "firstContentfulPaint": 0,
  "parseDomTime": 188,
  "initDomTreeTime": 307,
  "readyStart": 1,
  "redirectCount": 0,
  "compression": 0,
  "redirectTime": 0,
  "appcacheTime": 0,
  "lookupDomainTime": 0,
  "connectSslTime": 0,
  "connectTime": 0,
  "requestTime": 273,
  "requestDocumentTime": 271,
  "responseDocumentTime": 2,
  "TTFB": 272,
  "now": 775,
}

  在搜集到用户手机中页面的真实性能情况后,就可针对性的做各种优化。

2)系统监控

  系统监控包括服务器CPU、内存、负载、QPS等信息。

  这部分没有自研,而是直接接入了阿里云的Node.js性能平台

  前端稳定性建设

  当线上出现内存泄漏时,就能通过下载的堆快照导入Chrome中,以此来分析泄漏原因。

  前端稳定性建设

  还引入了阿里云的数据库监控,可以实时看到慢查询,并且还能智能的给出优化建议,自动生成相关索引,效果可以说立竿见影。

3)监控大盘

  监控大盘便于观察核心指标的走向,包括慢响应,5XX接口数量、白屏和首屏各阶段占比等。

  监控大盘也是为了能主动发现异常,而不是由用户上报。

  因为一旦发现曲线有异常情况,即迅速上升(例如下图),那么就需要抽调资源来排查是什么问题导致的。

  前端稳定性建设

  通过监控大盘,还可以发现一些用户并不关注的问题,例如前端监控在接收比较大的数据时会报大量的500错误,还有一些比较隐蔽的边界条件错误等。

  这些错误并不会非常影响用户体验,所以一般也很少会上报到客服,只能通过主动监控来发现。

二、告警

  告警也是为了能主动发现问题,及时处理,以免让用户感知,降低体验。

  告警主要还是针对后端用Node编写的服务。

1)业务接口

  业务接口就包括对外的H5网页和对内的管理后台所涉及的接口。

  目前的规则是每分钟5个以上5XX接口,就会自动在飞书中发消息告警。

nginx状态码告警
- 所属项目: k8s-log-xxxxxx
- 告警名称: 主站-5xx错误状态码
- 首次触发: 2022-08-23 02:24:46
- 告警时间: 2022-08-23 02:24:46
- 告警状态: 触发
- 告警严重度: 中级
- 错误状态码: 500
- 日志详细:
{
    'proxy_upstream_name': 'web-website',
    'req_id': '92072872edf58909e3f8f2edce6bc5f0',
    'status': '500',
    'url': '/share/live/xxx.html'
}

2)定时任务

  定时任务与接口不同,所以不能套用之前的规则。

  很多定时任务都是5分钟运行一次,那如果报错的话,也是5分钟一次。

  如果采用上面的规则,那么将永远无法收到告警。

  所以改成每5分钟有一次500的错误,就会发出告警。

三、事故

  当线上出现问题时,需要提前准备好应急方案。

  每一次线上事故,都是一次昂贵的付费学习机会,做好复盘,以免重蹈覆辙。

1)留一手

  如果能预判线上可能出现的问题,那么可以留一手,迅速响应。

  例如在某一时刻榜单定时任务可能会运行失败,那么就预设个页面,手动触发。

  页面可以像下图这样,下拉框就是各类接口名称,可自定义参数,按钮请求接口。

  前端稳定性建设

2)责任人

  公司内部有个技术问题对接大群,各类版本和H5需求还有单独的群。

  所以在将问题抛到群里后,可相对比较快的找到责任人。

  对于最近上线的业务,我们都会安排专门的人随时待命解决问题。

  在解决问题后,马上预估影响面,并告知业务方。

3)做复盘

  复盘有固定的格式,包括名称、持续时间、影响范围、经过、原因和解决方案。

  写好后发一封公司邮件,告知所有人这次事故的来龙去脉。

  复盘不是为了*,而是为了更好的找出问题,更好的修复问题,不要再犯相同的错误。

  有必要的话,还可以将所有相关人员拉上,组织一场会议。

  大家各自发言,看看是否还有其他没有注意到的问题,都抛出来。

四、测试

  公司有一个测试团队,当大家研发完成后,后面的流程就会转到他们那边。

1)自行测试

  测试团队会出一份测试用例文档,他们会给出部分需要自测的用例。

  当自测完成后,再去发一封提测邮件,然后他们再接手。

  之所以要自测,是因为在测试验收时经常发生主流程都跑不通的情况。

  还需要让研发修改,这样来来回回非常影响效率,所以才会要求自测。

2)单元测试

  单元测试是我们组内部一直在推,但收效并不明显。

  好处毋庸置疑,之前专门做过分析

  上次升级Node环境版本时,因为一个服务没有连接,导致一个接口报错。

  因为影响范围很小,所以也没有在第一时间收到反馈。

  后面与运维沟通,发现可以在线上发布的时候增加一个单元测试的流程。

  前端稳定性建设

  在单元测试中,写一些代码验证服务是否连通,若无法连通就断言失败,从而阻止后续的构建和部署。点击测试报告,还有专门的分析页面可以查看。

  需要注意的是,在单元测试中不能在数据库中增加数据,以免造成线上数据的混乱。

3)回归测试

  测试组会在我们修改完BUG后,会做回归测试,不过目前是依赖人工回归。

  测试组最近正在研发自动化的回归,有望以后也集成到代码发布流程中。

  对于一些有特殊要求的业务,测试组还会做压力和性能测试。

五、工具

  有句话叫能依靠工具就不要依赖流程,能建立流程就不要依赖人的主动性。

  在我们团队内部已经发布了协作流程、活动配置、Git分支管理等规范。

  在制订规范后,解决了很多问题,不过如果有工具加持,那么工作效率可以提升的更高。

1)自研

  根据公司业务和技术栈,我们组自研了很多工具。

  榜单活动配置直接释放了4个组的人力,从原先的3天开发时间,降低到了1小时,经过时间的沉淀,活动也能更稳定。

  通用配置已服务于5个小组,大大降低了开发和测试成本,不用再为一个小需求大动干戈。

  BFF平台减少了接口的开发和调试成本,以及冗余的增删改查代码,加速与页面的联调。

  依托VSCode开放的API,自研了一个插件,可以选中某个方法,直接从路由层跳转到服务层的声明处,便于查看源码逻辑。

  前端稳定性建设

2)第三方

  有些工具还是需要第三方提供,我们或是直接使用,或是做一层封装。

  在研发过程中,我们会频繁地将自己分支与测试分支合并,然后再手动发布代码。

  后面将合并与发布自动关联,合并后就自动去发布代码,减少了枯燥的手动操作。

  要访问公司的管理后台需要进入内网,内网会限制IP,需要先将IP加入到白名单内,才能访问。

  原先是运维手动添加,但是有点工作量,后面就根据阿里云提供的接口,我们自行创建了一套管理界面。

  后续增加、删除和查询都在此管理界面中操作,权限也开放给了相关人员。

3)Code Review

  Code Review的好处在有很多人分析过,不再赘述,团队内部已举办十多场。

  我们组会对比较重要且复杂的业务做Code Review,目的是为了发现研发人员没有想到的问题。

  当大家在看代码和理解其思路时,可以对写法、逻辑提出自己的看法。

  还可以避免在协作时才会发现的问题,尽早解决减少损失。

  顺便说下,为了提升技术氛围,内部的技术分享也在持续推进中,已举办二十多场,成员轮流主讲。