0%

快手极速版客户端春节稳定性保障

1 背景

同快手App一样,快手极速版App也会参加2020央视春晚活动,考虑到春晚活动时产品DAU会突增,有大量的网络请求从客户端发出,容易打死服务端,导致客户端界面展示异常,核心功能不可用,春节活动无法顺利开展等。因此通过对客户端API网络请求进行精细化控制减少对服务端的压力,保障核心功能和春节活动变得非常重要。

2 关键问题

整个App稳定性保障客户端侧的关键问题大致有三个:

  1. 任务相关:具体实施哪些行为来控制API请求;
  2. 组织相关:整件事情涉及的人数广团队多,包括基础团队和各个业务团队,整个几百人,如何推进保证最终达成目标;
  3. 效率相关:在任务实施的过程中,如何保障质量效率。

3 任务相关

具体实施哪些行为来控制API请求呢?我们认为大致有两件事要做:

  1. 设计并用代码实现一套行之有效的稳定性策略来限制不必要的请求以及保障真正重要的请求
  2. 确保这套策略确实能达到效果且对App核心数据无明显负向

3.1 策略

经过讨论,我们决定使用一套json来同时下发稳定性策略和春晚活动策略,这样只要保证这套json能正确触达用户,整个春晚活动就能玩得转。同时这套策略也必须要保障能正确触达用户,不然后面的事情就无法玩转。

3.1.1 实时高可用

首先需要保障策略高可用,在路径侧我们大概做了四层,第一层是从接口下拉的策略配置,第二层是从CDN下拉的策略配置,第三层是本地缓存的上次成功从接口获取的配置,第四层是客户端本地兜底配置,每个策略自带版本号,高版本可覆盖低版本,反之则不行。同时在实时触达方面,我们大概做了两件事,首先每次冷启动需要拉取策略,其次通过APP的心跳接口给客户端下达最新版本号,客户端对比本地版本号和网络号后决定是否获取最新策略。

3.1.2 API限流

针对一些运营类接口比如用户引导弹窗配置接口或者是App体验优化类的接口比如启动直接获取魔法表情列表,离线包配置信息,这些接口可以做限流。具体是把App的生命周期划分为几个关键的时机,改造业务请求带上请求时机标记,则API限流策略可以通过配置使得指定API在部分时机内不发出请求,直接返回。可能的关键时机包括:冷启动、首页创建、切换前台、切换后台、登录、登出、获取到AB、网络状态改变、默认等等。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"api_degrade": [
{
"paths": [
"/operation/foo",
"/optimize/foo"
],
"time": [
"cold_start",
"homepage_create",
"foreground",
"background",
"login",
"logout",
"after_ab"
]
}
]

3.1.3 API延迟打散

一些客户端日志上报请求会定时上报日志,如果这些请求被限流,则在限流时间内日志会堆积在本地,一旦API限流放开限制,则这些高频的定时上报日志请求会在短时间内把大量堆积在本地的日志发送到服务端,首先这些日志的上行流量比较大,其次这些日志几乎会在放开限制的同时向服务端发送请求,造成服务端高峰值。为了削峰,我们做了API的延迟打散,即把请求延迟到一个随机时间后再发送。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"api_delay_and_rand": [
{
"feature": [
"push"
],
"delay_time": 10000,
"rand_time": 10000
},
{
"feature": [
"client_log"
],
"delay_time": 10000,
"rand_time": 120000
}
]

3.1.4 API最小请求间隔

部分请求可能在切换前后台时发送或者有本地轮询,如果一旦频繁切换前后台或者轮询频率过高,则依然有可能把服务端打垮。因此我们做了一套兜底的策略,即限制每个请求的最小请求间隔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"api_min_request_interval": [
{
"paths": [
"/foreground/foo"
],
"time": 30000,
"ignore_time": [
"default"
]
},
{
"paths": [
"/roll/foo",
],
"time": 60000
}
]

3.1.5 API转CDN

针对一些核心的基础功能接口,比如发现,同城,热门或者是一些春节活动相关核心接口,需要强化保护策略。具体是采用CDN兜底,如果API请求失败,则拉取CDN数据,或者甚至可以不请求API直接请求CDN,当然这是针对API大规模不可用的一种预案。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"api_to_cdn": [
{
"path": "/infra/foo",
"cdns": [
"a1.static.com",
"a2.static.com"
],
"cdn_path": "/{cdn}/degradation/infra/foo.json",
"use_api_first": true
},
{
"path": "/spring_festival/foo",
"cdns": [
"a1.static.com",
"a2.static.com"
],
"cdn_path": "/{cdn}/degradation/spring_festival/foo.json",
"use_api_first": true
}
]

3.2 验证

做好策略后,我们需要验证策略的效果。要确保这些稳定性策略确实生效,并且对App核心数据没有明显负向。

3.2.1 本地测试

策略的本地测试主要通过网络代理来监听客户端的API请求情况,判断具体场景下的限流是否生效,或者API请求是否转换为CDN请求等。同时端上在一些代码核心节点,比如策略被更新、某个API命中了某个具体策略,等等打上端日志来辅助QA判断或者研发定位问题。

3.2.2 线上演练

降级演练也是必须操作,通过演练来验证降级效果发现降级中的问题。我们进行了2次大的演练,元旦,小年,还有一些常规的演练。大致发现了有些API降级不生效、降级恢复后峰值过高等问题。

3.3.2 AB实验

我们预先选择了一系列的运营类、性能优化类、以及部分功能类的API接口作为降级备选对象,按照预估的影响范围有梯度的做好三套配置。把这三套配置接入到实验平台,加上base组一共四组进行对照,大致判断降级后对App核心数据的影响,比如播放时长,新增次留等等。最终选出两组配置。

4 组织相关

不管是策略的实现还是验证以及最终上线都需要人来做。春晚API稳定性保障这件事显然不是一个人能搞定的,那是怎么划分任务,做到人事匹配,顺利落地呢?

4.1 职责划分

大略分为两类人,一类是owner团队,对整个事情的最终落地负责。主要包括服务端,客户端和QA,负责讨论策略,开发代码,组织各种策略验证以及上线策略等等。另外一类是配合团队,来自各业务线,负责配合把这个事情落地到各业务线,他们大多数是来自业务线团队的资深工程师或技术负责人,做的事情主要是向owner团队提供必要信息,比如梳理某个API的上下行流量,是否可以在启动时屏蔽某API等等。

4.2 流畅协作

跨团队参与的项目,必定存在很多信息不对称的问题,简单信息群聊或者线下单对,重要信息通过开会来同步。整个项目大致有如下几种会议。

  1. 日例会,与会人员多是owner团队内部成员,会议集中在策略设计、研发和本地测试期间,基本是在讨论设计缺陷、研发bug的解决情况等等。更多是一种决策性的会议,群策群力来解决策略落地的各种技术问题。比如,刚开始设计的协议可能比较冗余,会占用较多的下行带宽,在每日会议中提出了新的设计等等。
  2. 复盘会,每次演练都会发现问题,这种问题会梳理出来,然后分发给业务线,业务线派代表来参会,主要是定位问题产生的原因并提出解决方案。比如,某些业务侧API降级不生效,某些API在降级完成后,立刻出现尖峰等等。
  3. 布道会,布道会的主要目标是让相关人员学习特定的知识或技能,比如内部新开发的策略修改上线工具如何操作,这些需要业务线和owner团队的成员都要会用。
  4. 协调会,这种会议的主要作用是确立共同的目标和行动方针,达到认识和行动的协调一致,比如告知大家xx号会进行演练,演练的大致时间和流程安排,需要参加的人员等等。

5 工具链建设

除了任务本身很重要以外,还有一块是给任务提效的工具的建设,保障项目落地的质量与效率。

5.1 策略修改上线

策略修改上线有几个难点:

  1. 策略本身是一个很复杂的json,涉及的字段有几百个;
  2. 里面的有些字段是特定格式,比如跟时间挂钩,还有些字段是enum,只有特定的几个有意义的值;
  3. 策略上线之前还有diff配置,以及review的需求,不能简单直接上线。

为了解决以上痛点 ,我们做了一个系统工具来简化策略的配置与上线流程,目标是避免格式出错,且标准化上线流程,大致操作是界面化输入,不用直接操作json,自动diff配置发送给reviewer,reviewer确认才能上线。

5.2 代码同步优化

快手App和快手极速版App是两拨人在维护,参与到owner团队的也是两拨人。主要的代码实现由快手App的同学完成,极速版App的同学更多的时间在做代码同步以及功能可用性验证的工作。因此实时监听快手App的代码变更变的很重要。我们专门做了个gitlab hook,监听快手App的基础库升级情况,发现指定同学的升级会推送一条消息到快手极速版的群里,实时查看代码判断是否跟春节稳定性相关。

6 总结

图片

2020春节已过,快手极速版春节客户端稳定性保障项目也最终成功上线。很幸运能有机会参与到这样一个有纪念意义的项目,事后反思推一个技术项目的方法好像也就大概这三部曲,任务分拆,人事匹配,提质提效。