弱网优化在支付宝的深度实践 | mPaaS 线下沙龙 CodeDay#1 分享实录

作者:凝睇,蚂蚁金服移动开发平台 mPaaS 技术专家。目前负责蚂蚁金服移动开发平台 mPaaS 服务端组件体系优化与架构设计。 内容采编自 CodeDay#1 杭州站现场分享,主题是《弱网优化在支付宝的深度实践》。

现场视频: tech.antfin.com/activities/…

0. 背景

随着 PC 端场景越来越重,其发展已日趋饱和,而随着智能移动设备的兴起,移动互联网呈现出了井喷式发展形态。相比于 PC 互联网时代的有线网络,无线网络通信的稳定性却有着巨大的差别;因此,开发者总会面对用户反馈诸如 App “不通”、“不快”等各种“网络问题”。

作为国民级 App,支付宝需要服务在各种复杂的移动网络环境下的亿级用户,因而在网络优化的道路上也是一走就很多年,本文的目的即是将我们遇到的问题做一个总结,并把在一些实际可行的优化和实践经验分享给各位开发者,期望能从某个角度能给各开发者提供一些灵感以帮助大家建设更好的移动 App。

问题归总

网络问题,从用户反馈过来的表象可分为“不通”或者“不快”,这两词虽然只有一字之差,但本质却完全不同:

  • “不通”,一般为服务可用性的问题,比如:由服务器宕机引起的“网络异常”、“操作无响应”、“白屏”或者“完全收不到消息”等问题;
  • “不快”,则一般为真实的性能问题,比如:“转菊花”、“操作响应慢”、“消息接受慢”等。

对于“不通”的问题,主要原因为客户端真实网络确实不可用或者服务端系统稳定性不足导致,从优化的角度,更偏向于优化服务端架构设计或者从交互角度让客户端在异常情况如何更友好的呈现给用户,而对于“不快”的问题,我们则可从技术上做更多的优化和改进,因而也是本文的重点。

问题来源

首先我们来看一下移动网络的链路:

  1. 移动端通过无线网络协议,从运营商的基站获得无线链路分配用以满足跟网络进行通讯;
  2. 运营商的网络基站、控制器,给移动终端进行信号的分配以完成与终端的连接和交互;
  3. 获得无线链路后,会进行网络附着、加密、鉴权,核心网络则会检查终端是否可以连接在这个网络上,是否有开通套餐,是不是处于漫游等。目前核心网络有 SGSN 和 GGSN,这一步主要目的是完成无线网络协议和有线以太网的协议的转换;
  4. SGSN 和 GGSN 核心网络会根据终端的情况进行 APN 的选择、IP 分配、并启动计费;
  5. 之后才是我们所接触的传统网络的步骤:DNS 查询、响应,TCP 链接,HTTP GET 请求,RTTP RESPONSE 200,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA 和 UI 展现等等。

由此可见,移动网络本身链路上就相较有线网络复杂很多,同时终端因为其强烈的“移动”属性,在很多场景下网络情况确实不如人意,比如在地下室、电梯、偏远地区等等,总会带来带宽不足、频繁丢包、高延迟的问题。与此同时,在进入后端服务器应用网络之后还有一层层的防火墙、路由器、负载均衡、IDC 分机房部署。 再到客户端应用程序、服务端的系统设计、接口设计等问题也会极大的影响到在弱网环境下用户的体验,如:

  1. 客户端启动时各种并发 RPC 请求导致网络或者线程拥塞
  2. 服务端流程设计冗长,慢 SQL 等;
  3. RPC 接口模型设计沉重,请求或相应模型大量冗余数据;
  4. 静态未压缩,或者未分网络环境,不分用户使用场景进行资源拉取导致首屏堵塞,迟迟未响应等。

除此之外,传统网络协议在流程设计上限定,如果移动 App 自身没有进行改良和优化,在弱网环境下也可能会成为绊脚石。

如:

  1. TCP 传输过程中为防止过多的数据注入到网络中,会先探测一下网络的拥塞程度,会有由小到大逐渐增加拥塞窗口的大小;
  2. 在绝大部分 App 中,均需要进行SSL链路加密,因此需要耗费 2 个 RTT 来做证书的交换;
  3. 除此之外,不同运营商、在不同地区对于 DNS 域名解析的支持能力也有所不同,绝大部分需要 1 秒以上,在某些情况下甚至可能超过7秒,并且此处也需要消耗 1 个 RTT。
  4. 通过分析上面的几个可能产生问题的根源,我们基本就可以知道在网络链路上、客户端&服务端流程设计上、以及网络协议上本都做一些事情来达到优化的效果。

1. 优化指标

做优化一定需要有可量化的指标来衡量和记录我们的劳动成果和效果,因此,可以主要从以下几个指标入手:

  1. 建连成功率:可通过客户端端埋点的手段进行开展,并通过MAS的数据采集和数据分析等功能来记录、统计、分析;
  2. 建连时⻓(耗时):依然通过客户端端埋点的方式,来记录、统计、分析耗时信息;
  3. 连接保持时长:此处可以在服务端和客户端分别进行实时,主要用以评估终端 TCP 连接的稳定性;
  4. 移动网关 RPC API 方法的调用成功率(错误率)包大小耗时等;
  5. MSS、MPS 数据同步推送成功率耗时包大小等。

其中各种指标均需要区分网络类型(WiFi、4G、3G等等)、机型等参数进行分别监控,至于其他的数据则可根据不同场景继续延伸挖掘,并可针对诸如“当面付”等重点业务做专题分析。

2. 优化方向

在前面的章节已经有提到,根据移动网络的特性,我们可以分别从网络链路上,客户端&服务端流程设计以及网络协议上下手,在实际的操作过程中,则通过以下几方面开展:

  1. 网络服务架构升级:主要组成部分为AccGW网络接入网关、MGS移动API网关、MPS消息推送服务、MSS数据同步服务以及MDC移动调度服务。
  2. 定制网络协议:MMTP(蚂蚁移动传输协议)+MTLS(蚂蚁移动安全传输协议);
  3. 网络数据处理:HybridPB 序列化、gzip、zstd、hpack 等压缩方式升级;
  4. 连接策略细化:建(断)连控制、连接保持、智能心跳、假连接侦测等;
  5. 持续业务治理:接口设计优化、静态资源优化、监控体系建设等。

网络服务架构升级

如图中所示,客户端可拆分为主进程和 Service 进程,主进程主要承载具体的功能组件和业务模块,Service 进程则主要负责与服务端进行网络协议和网络数据对接,并负责进程保活。

在穿过公网、LVS、以及一系列防火墙、路由器之后,进入后端具体应用可直接感知 SLB,在这之后才正式进入我们可操作和优化的后端架构:AccGW、ApiGW(MGS)、SyncGW(MSS)、PushGW(MPS),并由 LinkMng 来统一管理终端的连接信息和连接生命周期,移动调度这使用 MDC 配合 HTTPDNS 来完成。

AccGW

接入网关目前由 Spanner 来承接:

Spanner 是蚂蚁集团基于 Nginx 二次开发的一套事件驱动型系统,其主要功能大致可分为:

  1. 进行 SSL 卸载:可支持标准的 TLS1.0、1.1、1.2、1.3 以及 mtls;
  2. 配置管控:可通过控制台动态的管理配置项、上线、下线,并提供一系列的API可供后端系统动态调用;
  3. 动态 UPSTREAM 路由:因需要对接不同的基于 mmtp 协议的后端基础组件,因此需要区分数据包渠道类型(upstream 路由到哪个基础组件),并可实时、动态的挂载和下线后端服务器;
  4. MMTP 协议处理:包括数据的序列化、反序列化、压缩、解压缩;
  5. 连接保持:需要挂载所有终端的 TCP 连接,并通过智能心跳维持住连接;
  6. 数据埋点:可在最上层进行数据包的埋点记录,并用户监控体系为后续流量管控及网络分析提供一手数据。
  7. 流量管控:其核心目的是在大促场景下,可在最上层将业务流量进行限制和管理,以确保下游系统能安全存活。

MSS 消息同步服务

在基础服务架构升级中,MSS(SYNC)的出现同样扮演了及其重要的角色:

在之前的文章中已经有介绍 MSS 是通过一个安全的数据通道 TCP+SSL,及时、准确、有序地将服务器端的业务数据,主动的同步到客户端 App,其定位是一个客户端与服务端之间的消息中间件。

MSS 主体思想是:类似 MySQL 数据库 binlog 原理的基础上定义了一个 oplog 概念,服务器和客户端 SDK 之间传递的最小数据单元被称为一个 oplog,每当业务需要同步一个数据变更到指定的用户/设备的时候,业务调用MSS服务端的 SyncData 接口,MSS 会将业务需要同步的数据变更包装为一个 oplog 持久化到数据库,然后在客户端在线的时候把oplog 推送给客户端,如果当前则立即触发推送。每个 oplog 拥有一个唯一的 oplog id,oplog ID 在确定的用户、确定的业务范围内保证唯一并且单调递增(按调用顺序)。MSS 按照 oplog ID 从小到大的顺序把每一条 oplog 都推送到客户端。通过 ACK 机制服务端和客户端均会记录客户端已同步数据的最大 oplog ID(亦可理解为数据版本),后续产生新数据时进行差量计算和差量同步。

通过 MSS 可以给客户端带来几大好处:

  1. 业务合并:一次初始化命令,推送多业务数据,减少冗余的请求数据;
  2. 增量推送:增量数据相对较少,减少冗余数据的传输,降低网络成本;
  3. 减少请求:没有增量数据时,将不会消耗请求成本,减少了无谓的请求;
  4. 提高时效:当服务端发生数据变化,可以直接推送至客户端,无需等待客户端请求;
  5. 提升体验:在渲染界面之前,数据已经到位,降低了用户等待的时间;

这些优势可非常有效的减少客户端 RPC 接口交互次数,减少需要传输的业务数据内容,并由于其主动推送的特性又可极大的提升用户的体验效果。

移动调度

在移动调度的升级上,采用的是 MDC 配合 HTTPDNS,传统的 DNS 有几大弊端:

  1. 终端网络请求需要消耗 1 个 RTT 先进行域名解析,需要额外的网络和时间开支。
  2. 运营商 DNS 参差不齐:不同的地区、环境、不同的运营商 DNS 解析效率完全不同,快则1秒,满则 7~8 秒甚至由于缓存等问题解析失败。
  3. 目前大型 App 均需要进行多机房、多中心部署,传统 DNS 无法在客户端直接路由到指定机房或中心,并且由于缓存等问题容灾效率也不高。
  4. 无法满足自定义的调度需求:灰度、白名单、特殊业务场景指定到具体机房、中心或指定到某一个台服务器上。
  5. 存在 DNS 劫持问题。

通过 MDC 配合 HTTPDNS 则可以完美的解决以上问题:客户端通过独立的网络请求到服务器拉取可用的 IP 列表,IP 列表信息中已包含了服务端的机房、中心以及白名单相关信息,客户端在获取到 IP 列表之后既可根据当前用户(设备)信息在后面的网络请求中直接路由到对应的机房、中心、某台具体服务器或者海外 POP 加速站点。IP 列表可长期的保存在客户端中,后续的请求中均只需要通过本地 DNS 解析即可以完成 IP 映射,用以节省 1 次 RTT 请求时间,也可以有效的防范 DNS 域名劫持,于此同时可结合 MSS 等服务来指定实际更新策略来确保第一时间更新 IP 列表。此外,客户端也可通过定期检测、定制质量模型等方式来计算、评估获取最优 IP 地址。

协议优化

  • MMTP

MMTP:全称蚂蚁移动传输协议,是二进制的 TLV(类型、⻓度、值)结构的协议;是并驾于 HTTP、HTTP2.0、spdy 的私有化传输协议。

其主要优点为:

  1. 打包解包效率高,省内存;
  2. 可多路复用,并具有极高的扩展性;
  3. 由于高度的自定义,引入了诸多的特性,如:数据包重发、Sequence 检测假连接、柔性断链并可做到精细管控等。
  • MTLS

MTLS:全称蚂蚁移动安全传输协议是基于 TLS1.3 扩展的安全传输协议。

TLS1.3 可通过证书 cache、session Ticket 等机制支持 1RTT 握手,加密套件则可选用ECDHE,根据有关数据验证,160 比特 ECC 密钥和 1024 比特的 RSA 密钥的安全性相当,小数据量在速度、效率、带宽、存储上都会体现出明显优势,此外在某些特殊功能上,甚至可以使用 0RTT 的方式直接完成数据交互。

数据优化

  1. 序列化方式:目前在蚂蚁体现内已基本普及了 protobuf。Protobuf 全称 Google Protocol Buffer,是一种轻便高效的结构化数据存储格式,主要满足结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

    而通过 protobuf 官方工具生成的客户端文件较大,可能会引起安装包过大,函数方法过多等问题,蚂蚁内部在此基础上又重新定制了生产工具,最终产出物被定义成 HybridPB。

  2. ZSTD 压缩算法:在上一代产品中业务数据 body 主要使用的 gzip 压缩,而在目前的产品中则主要采用了 ZSTD 压缩:

    ZSTD 全称 Zstandard,是一款免费的开源,快速实时数据压缩程序,具有更好的压缩比,由 Facebook 开发。 它是用 C 语言编写的无损压缩算法 (在 Java 中有一个重新实现) , 因此它是一个本地 Linux 程序。在移动网络中,它可以需要将压缩速度交换为更高的压缩比率(压缩速度与压缩比率的权衡可以通过小增量来配置),它具有小数据压缩的特殊模式,称为字典压缩,可以从任何提供的样本集中构建字典。更高的压缩比意味着更小的网络传输成本消耗,而这也是在移动端被采用的主要原因之一。

  1. HPACK 压缩算法:网络协议上,压缩算法目前采用的是 HPACK。简单的说,HPACK 使用 2 个索引表(静态索引表和动态索引表)来把头部映射到索引值,对不存在的头部使用huffman编码,并动态缓存到索引,从而达到压缩头部的效果。

连接策略

TCP 建连行为由移动终端发起:目前主要在终端启动时、前后台切换时、网络超时、连接错误或者网络类型切换时会发生建连动作,而建联的策略上主要由以下几种:

  1. 并行建连:当客户端串行建连失败一定次数后、则会进入并发建联模式,期目的是为了并发争取信道,增加建立成功率。
  2. 短频建连:在弱网情况下可加快建立连接的频率,以踩中一闪而过的可用间隙,第一个链接还没建上,也可开始第二个。
  3. 柔性断连:因并发建联引起,某些场景业务可做重连重发,因此对可能并存的多条连接,需要做延迟回收,以等待在这条即将被回收的连接上的可能存在的回包。
  4. 长短连接并存:在某些场景下,因为tcp无法长久保持,则可通过http短连接来提高请求瞬间冲击能力,快速完成业务请求,并释放资源。

对于连接的保持,传统的做法就是心跳,心跳包可由客户端发起,也可由服务端发起。由于移动端终端的运营商、手机厂商等各种定制、非定制的因素干扰,对于 TCP 连接保持能力上各不相同,因此恒定的心跳时间未必能满足各种情况,过快、过慢都会带来问题,因此支付宝采用的是动态心跳的方式来维持连接,客户端通过一定的质量模型来评估某一心跳周期的连接维持质量,并在过程中逐步增加或减少心跳周期,在到一个最优的模型质量之后记录下最优心跳时间,并用改周期时间来维持之后的一段时间。

连接超时控制上:除了传统的业务请求超时和建连超时,还引入了包 sequence 概念,每个上行包发送时,加入递增序号,服务端收到带序的包后,如果有下行包,就把当时收到的最大序号返回给客户端。客户端收到后,既可确认所有小于等于这个序号的上行包都已被服务端接受;如果某个上行包的序号在一段时间还没有收到确认,可怀疑出现“假连接”,需要进入回收评估阶段,服务端下行包亦然。

3. 业务治理:持久战

在上面的内容中,我们一直在基础服务上做文章,而实际的生产过程中,业务接口的设计也极大的影响着用户的真实网络体验,并且由于业务在持续发展,人员也持续的迭代,对于优化的规范和设计的思路上并非都在同一水平上,因此业务治理绝对是一个需要持续坚持不懈战斗的过程。在业务治理过程中也可总结为几个方面:

  1. 接口设计优化:主要为接口数据模型设计需要在满足业务功能的基础尽量精简、减少不必要的数据传输;客户端并发请求优化,区分优先级,让客户端在合适的场景做合适的事情,千万不可大量并发争抢资源而影响用户核心流程的使用,服务端接口流程优化,比如采用异步、缓存、减少慢 SQL 等;
  2. 资源拉取策略优化:使用更快捷的图片格式、在不同网络环境使用不同缩放程度的图片、资源合并、图片压缩等;
  3. 减少数据量、数据包大小:推广各业务方接入例如 PB 等更高效的序列化方式,推荐业务接入 MSS,SYNC 服务,通过增量推送的方式减少客户端请求次数与服务端返回数据的大小;
  4. 监控体系持续完善:全链路数据打通,问题剖析一杆子到底;多维评价模型,监控预警,数据化研发;做到管控决策有依据,结果有数据,推动有根据;
  5. 大户专项治理:针对重大业务、核心业务,网络同学直接深入业务流程设计,协助业务方发现问题并推动不断改善。

最后: 持之以恒。无论是性能优化、网络优化,都是一个长期的过程,这也将伴随着整个终端和服务端的生命周期,因此持之以恒的优化改进才是重中之重。

*注(更多详细内容):

| 移动开发平台 mPaaS 三款组件重磅上线蚂蚁金服开放平台:

往期阅读

《开篇 | 蚂蚁金服 mPaaS 服务端核心组件体系概述》

《蚂蚁金服 mPaaS 服务端核心组件体系概述:移动 API 网关 MGS》

《蚂蚁金服 mPaaS 服务端核心组件:亿级并发下的移动端到端网络接入架构解析》

《支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能》

《支付宝 App 构建优化解析:Android 包大小极致压缩》

关注我们公众号,获得第一手 mPaaS 技术实践干货

QRCode

钉钉群:通过钉钉搜索群号“23124039”

期待你的加入~

猜你喜欢

转载自juejin.im/post/5ca5c174f265da30cc7919d1