淘宝HTTP3/QUIC技术演进与实践

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 淘宝HTTP3/QUIC技术演进与实践



文章介绍长链通道进行端云链路HTTP3/QUIC基建升级改造,目前淘宝自研实现的QUIC标准实现XQUIC库已历经多次双11在核心导购&交易等RPC场景/上传链路/短视频链路大规模应用,持续改善长链通道网络传输能力,助力多业务提升网络体验,,沉淀出一整套可被横向复用的HTTP3/QUIC标准协议落地解决方案。


引言

下图示为淘宝网络协议演进关键节点。2015年为优化标准TLS/1.2握手慢问题,我们自行研制上线了轻量级私有加密协议Slight SSL来优化握手与加密问题,在没有重放攻击风险时允许将会话协商和数据加密放在一个TCP报文中来实现0-RTT,目前手淘线上流量HTTP2+SlightSSL也是主要承载者。与此同时过往问题排查/业务接入/业务诉求面临一些疑难或者无法满足诉求问题,诸如 "WI-FI下长链全失败降级短链https可以成功,切换到4G网长链正常使用(SlightSSL私有协议被wifi防火墙断开)"、"你们计划支持TLS1.3吗?"、"我们域名接入服务端不支持部署SlightSSL"等;另一方面随着QUIC RFC9000、HTTP3 RFC9114正式发布,将淘宝网络协议演进到HTTP3/QUIC不管是解决Slight SSL私有协议在业务上痛点,还是为了提高网络传输性能提升用户体验,同时也是当下网络协议向前演进的大势所趋。私有化协议带来高效网络体验的同时,归纳起来问题主要集中在以下三点:

  1. 私有化的协议意味着更定制,需要端到端的部署支持(侵入性)
  2. 不支持TLS1.3
  3. 偶有网络中间设备因私有协议同时断开两端连接

图1.1 淘宝网络协议演进关键节点


TNET能力演进


TNET 全称 TAOBAO NET,是在淘宝无线化发展和演进中,逐步形成的一套底层网络基础能力库。目前承载了淘宝 90%+的业务HTTPs数据流量(少量域名AMDC未配置长链协议),作为集团网络服务在端侧落地的基石,是端上到服务端的长链通道端侧入口,同时也是端上网络相关中间件的底层基础。经过演进完善目前对上层提供丰富可组合的协议搭配,内部对不同协议进行实现&抽象适配,对外接口上提供统一的接口,外层只需要在建联时传入不同组合协议类型即可,做到真正意义上的简单易用。目前内部功能上主要有两大块:

  1. 一块由SPDY/HTTP2/HTTP3/Custom/HTTP3/Tunnel对上层满足HTTP网络请求/上传私有协议通道/ACCS消息网络通道能力(其中标准TLS主要为海外等部分不支持SlightSSL部署业务使用,标准HTTP2目前采用分支维护未合入手淘主干,原因主要基于手淘集成下包大小考虑,手淘下SlightSSL即满足业务要求且性能更高)
  2. 另一块为提供自实现DNS解析/traceroute/MTU探测/ICMP PING探测/IPv4&IPv6协议栈探测能力,主要偏网络工具属性满足上层对网络诊断/探测能力的支持,以及部分对原生DNS接口失败情况下系统能力的补充。

图2.1  TNET能力架构


HTTP3/QUIC协议升级提性能


 端云升级技术改造方案


XQUIC作为淘宝自研IETF QUIC标准的协议库具备完全自主可控快速演进的优势,关于XQUIC协议库的设计部分组内同事已有多篇文档进行详细的介绍不再重复,感兴趣的可通过本文尾部的相关文章链接查看。回到端上TNET网络库来说,通过适配XQUIC库全面升级增加支持七层HTTP3协议和四层QUIC协议,同时对外屏蔽掉各协议实现上的差异,上层只需建联时选择不同的协议类型即可,满足多种业务场景下不同诉求。


图3.1  XQUIC淘宝集成改造方案


  • 端侧降级&快恢


端上会先从amdc拉取一组策略 (amdc可以理解为一个扩展的httpdns域名解析服务,不仅会返回域名对应的ip,还有支持协议等扩展属性),这时amdc会同时下发http3&http2协议(端上优先使用http3,同时下发http2协议是为确保有兜底长链协议),拿到http3协议后会先进行udp连通性探测规避udp受限问题,只有当前网络环境探测通过后的才会新建HTTP3长链,关于探测部分文章后面会有介绍。


图3.2  客户端降级策略


 升级效果


  • 大盘升级进度&效果


前年在淘宝重点联路完成IPv4流量部分的HTTP3升级覆盖,去年随着Aserver主站内网QUIC IPv6链路改造完成,我们将导购/交易/短视频/上传链路原先走TCP+IPv6这部分流量也全部切到QUIC,目前淘宝里这几个重点场景已完成全部覆盖升级。效果上大盘/业务AB数据显示HTTP3/QUIC在这些不同类型业务场景下都取得显著提升,助力业务实现好网(传输速率/均值耗时)更好,弱网(长尾耗时&成功率)更优,为用户带来更顺滑的网络体验。除此之外,阿里集团内其他如菜鸟、手猫、AliExpress等APP也复用我们方案进行HTTP3升级覆盖,拿到更优网络体验的业务收益数据。以下是淘宝上收益提升情况:

  1. 导购场景:网络总耗时均值/P99降低22%/33%,一秒完成率提升1.2pt;
  2. 交易场景:网络总耗时均值/P99降低23%/32%,一秒完成率提升0.55pt;
  3. 上传场景:视频/图片 上传速率提升7.7%/21%,成功率提升0.18pt;
  4. 短视频下载:网络总耗时均值/P99降低15%/16%,下载速率提升18%;

图3.3 MTOP RPC核心链路升级对比数据


图3.4 上传&短视频内容链路升级对比

  • 数据典型业务场景效果


互动场景中断率


在互动业务下AB实验数据显示升级HTTP3实验桶可有效降低互动中断UV数/流失UV数。Android HTTP3 AB实验桶中断UV数/中断流失UV数分别降低 24.02%/22.89%,IOS端实验桶分别降低20.91%/18.57%。


图3.5 淘宝互动场景之一笆芭农场


购物车&详情


今年淘宝购物车改版后为用户下单带来了便捷,但同时也面临网络传输体验上耗时长的业务痛点问题,通过切换到HTTP3后从业务大盘耗时均值下降明显,给业务带来更多可能。如下图所示为HTTP3升级推量后接口大盘耗时变化趋势。其他详情/首页等接口也有类似表现,这正是由于升级后传输性能的提升所带来。  

图3.6  业务接口耗时随着放量趋势


 落地问题&优化


  • UDP穿透性问题


因部分运营商和网络中间设备可能存在将udp包丢弃的策略,这将拉低大盘建联成功率并导致降级率显著变高,往往需要等建联超时后才会降级重试成功,这显然会增加重试耗时导致不好用户体验。

对此我们设计了udp联通性探测,在启动阶段或者络环境发生切换时会触发异步探测,该探测结果会根据网络环境持久化到本地,在探测结果过期后会重新触发探测更新。这样确保了即使udp不通情况下,对上层业务体验也不会有劣化影响,而在探测通的环境下使用HTTP3/QUIC将为用户带来更优的用户体验,线上全国大盘的udp穿透性探测成功率数据平均值一开始在95%左右,经过对UDP质量差的VIP治理/下线历史不支持UDP端口特殊调度配置/运营商对某些UDP IP网段去黑名单处理,目前全国udp探测成功率均值提升到98%。


  • UDP端口NET-rebind问题


在TCP下五元组便唯一确定一条连接,过往我们SLB和CDN LVS的负载均衡分发基础算法都是基于5元组来实现,这在TCP下可以很好的满足要求。升级为QUIC协议后基于五元组转发对连接迁移(Connection Migration)和 多路径(Multipath QUIC)的能力就无法支持,因为在这两类场景下5元组都会发生变化。比较理想的是基于CID进行一致性hash转发,这也是QUIC协议设计之初便与5元组解耦考虑,关于基于CID分发感兴趣的可以查看草案QUIC-LB。回到我们落地由于涉及到SLB/LVS基建改造周期较长,受此影响一开始在单路落地我们基于5元组转发(舍弃掉连接迁移能力)进行业务应用,这在大多数情况下已经满足要求但也面临一些问题。NAT 网关针对 UDP 的 Session 存活时间普遍较短,在移动端因为用户切后台空闲情况下容易发生UDP端口NET-rebind问题,这时通过5元组转发下将无法分发到目标服务器,便会出现因为找不到连接上下文而导致连接中断即使当前网络正常。


如下图所示,客户端QUIC连接Q首先从NET设备源出口端口1被SLB转发到Server A上,连接Q从客户端到Server A链路双向转发传输正常;某个时刻如果连接Q对应的UDP Session空闲(如用户切后台)超过NET设备保活时间,APP与出口端口1之间映射将失效;等用户回前台触发发包后,NET设备重新建立起APP到出口端口2的新映射,此时客户端上来的包将被SLB转发到另一台Server机器C上,而在C机器上是找不到QUIC连接Q对应的上下文,这时会回复RESET导致连接中断,从我们数据看华为机型比例高于其他厂商。问题已经清楚通过CID转发来确保端口NET-rebind前后路由的一致性,当Servre端检测到新的5元组后触发连接迁移便可得到解决。


图3.7、五元组转发面临问题


  • 0RTT比例提升


在首次建连握手时,服务端会给客户端返回Session ticket和传输参数,客户端在Session ticket缓存有效期内,下一次握手即可在client-hello之后直接发送加密数据。同时Session ticket自动到期失效后可以退回1-RTT更新,在减少握手延迟的前提下,相较于公钥预置的方案更优,兼顾前向安全性。手淘上目前在完成首次1RTT建联后,我们会将Session ticket和传输参数存储在安全保镖中以确保缓存的安全性。在项目上线初期,提升效果并不那么理想,网络总耗时相较于H2提升约15%左右,分析数据在首包耗时方面与H2几乎保持持平这显然不符合预期,通过数据看0RTT连接比例一开始只有40%左右,经过优化缓存有效率后0RTT比例由40%提升到了65%(该比例还有进一步提升空间,短视频场景0RTT比例目前在80%+),网络总耗时相较H2的提升由15%提高到了20%左右。


  • 业务非加密诉求


对于一些短视频业务,响应大小相比RPC场景更大,且基本都是明文传输对加密诉求弱,更关注视频拉流的速率。为此我们在XQUIC中实现了加密/明文协商能力,在握手完成后如果协商结果为明文传输,则后续包都不再进行加密,这可有效降低server端/客户端加解密的处理开销,进而提升性能。


  • XQUIC协议栈性能优化


除前面优化外我们还对协议栈进行深度优化,就XQUIC库本身协议处理性能提升85.93%,对比nginx-quic在处理性能上也有15.62%的提升。


图3.8  XQUIC库协议栈优化对比数据


XQUIC库处理模型


下图是XQUIC协议栈最简化模型:对于发送方而言,XQUIC会把一段有序字节流封装成QUIC报文发送出去,对于接收方来说,是把一个个无序的QUIC报文组装成一段有序的字节流。


图3.9  XQUIC库处理简化模型


整体性优化


我们思考下优化CPU开销的核心是什么?为了回答这个问题,我们先想想CPU上跑的是什么?没错,就是指令集。那么指令集是怎么来的呢?它是由汇编语言生成的。汇编语言是怎么来的呢?他是由高级编程语言生成的。因此,我们至少可以想到以下几方面可以优化:

  1. 编程语言:也就是你的代码,选择一个合适的编程语言,然后想办法写的性能高一点
  2. 编译:编译优化,可以开的编译优化选项都开起来;编译器,选择一个高性能的编译器
  3. 指令集:这个我们能做的比较少,服务端一般都是X86
  4. 组包优化:回到上面的问题,优化CPU开销的核心是什么?本质上就是减少完成一个功能所需的指令数。注意看XQUIC的简化模型,每收到一个QUIC报文,都需要一系列的函数操作,最终输出一段流。相反的,每发送一段流,都需要调用一系列函数,最终输出一个个QUIC报文。我们要完成的功能就是把一段流传输给对端,我们可以优化处理每个包的一系列函数的性能,但是减少函数调用次数是不是来的更高效。减少QUIC报文数能大幅提升性能,在协议允许的范围内尽量填满每一个报文。

图3.10  XQUIC最初组包情况

图3.11  装填组包优化

图3.12  去掉冗余帧优化


局部性优化


  • 能不能不调
  • 避免无效计算
  • 避免重复计算 :每次加解密包都创建加解密上下文,并且初始化密钥 ->  握手完成时或者密钥改变时创建加解密上下文,并且初始化密钥
  • 能不能少调
  • 减少内存拷贝:业务拷贝到H3层再拷贝到传输层 -> 业务拷贝到传输层
  • 尽早退出循环:特别是遍历的列表很长时
  • 优化函数性能
  • 空间换时间 :huffman解码表 用4K数组存储,每次解码4bits -> 用64K数组存储,每次解码16bits
  • 函数内联
  • 分支预测 :likely()/unlikely()


集团全链路压测协议升级


 集团全链路压测升级HTTP3


在淘宝客户端导购&交易场景HTTP3大规模放量后,随之而来的大促全链路压测流量模型中协议占比也发生改变,全链路压测需同时支持HTTP2+HTTP3协议,对此我们对集团全链路压测引擎平台进行一次大的改造升级支持HTTP3协议压测。


不同于HTTP2基于TCP的已经过多年大促&压测多轮验证过的稳定链路,HTTP3基于UDP的全新链路在大促脉冲下的表现则显得缺少大促经验,确实通过压测前验证助力我们提前发现UDP新链路下一些问题,针对解决后最终确保双十一大促HTTP3平稳顺利。碰到的问题主要有:

1、udp_hash查找性能差问题:在quic连接数多的情况下,系统udp_hash查找的性能会急剧下降,易打满系统软中断而无法及时处理超时。内核对该问题进行过优化,4.19之前内核版本需要打patch,4.19及之后的版本已自带,该查找优化需通过设置socket option 来启用,为此我们升级内核版本到4.19。

setsockopt(s, SOL_UDP, 200, (const void *) &value, sizeof(int)

2、内核对udp丢包问题:升级4.19内核后在pps高的情况下又碰到udp丢包问题,原因在于4.19内核对udp内存存在限制。


具体原理:

对每个UDP session内核会把使用的内存计数,并累积到一定值(与rcvbuf正相关)才释放 2. 内核会记录所有UDP的的内存计数和,当这个计数和大于限制值(与umem正相关 )时 ,将会丢弃所有的UDP报文。


不难看出该问题会导致我们单机长链数和应对突增流量的受限,为此我们两个优化参数调节方向:1、增加umem值;2、缩小recvbuf值。


正在进行


 HTTP3覆盖图片域名


当前我们完成导购、交易、短视频、上传链路的全量升级覆盖,图片域名的升级覆盖还在逐步灰度覆盖中。


 HTTP3 over MPQUIC规模化应用


MPQUIC改造涉及到客户端、SLB、Aserver等基建的升级,目前RPC链路端到端整条链路已经改造完成。淘宝Android已正式上线目前处在规模化放量阶段,能力上提供两种可选模式(长尾补偿模式和多路并行加速模式),从灰度数据看加速模式下MPQUIC相比单路QUIC还有8%进一步速率提升,目前XQUIC实现的MPQUIC已对外开源。CDN链路MPQUIC支持改造Server端和LVS正在进行中。


图5.1  WIFI+LTE双路聚合传输示意图

图5.2  淘宝通用设置网络加速用户开关


附录

  1. QUIC-LB: https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers-15
  2. RFC 9000:https://quicwg.org/base-drafts/rfc9000.html
  3. RFC 9114:https://quicwg.org/base-drafts/rfc9114.html
  4. XQUIC: https://github.com/alibaba/xquic


团队介绍


我们是淘天集团终端平台网络技术团队,负责淘宝网络技术/高性能网关技术建设,包括但不限于Tengine-Ingress高性能网关/XQUIC标准化协议库/淘宝终端网络库,支撑亿万流量的移动网络接入和网关服务。团队持续迭代XQUIC/Tengine-Ingress等开源技术代表作,在SIGCOMM/NSDI等网络学术顶级会议发表过多篇论文,并于网络标准组织IETF推进MPQUIC RFC标准。
若你对我们的工作内容感兴趣,欢迎加入挑战,简历投递邮箱:miaoji.lym@alibaba-inc.com

相关文章
|
1月前
|
Rust 前端开发 API
Tauri 开发实践 — Tauri HTTP 请求开发
本文介绍了如何在 Tauri 中发起 HTTP 请求。首先通过安装 Tauri 生态中的工具包并配置 `tauri.conf.json` 文件来允许特定域名的 HTTP 通信。接着封装了一个简单的 HTTP 客户端类,并在页面中使用该客户端实现 GET 和 POST 请求。最后提供了完整的源码地址以供参考。此功能使得桌面应用能够与远程服务器进行交互,增强了应用的实用性。
89 1
Tauri 开发实践 — Tauri HTTP 请求开发
|
28天前
|
存储 缓存 NoSQL
保持HTTP会话状态:缓存策略与实践
保持HTTP会话状态:缓存策略与实践
|
1月前
|
存储 JSON API
HTTP 请求与响应处理:C#中的实践
【10月更文挑战第4天】在现代Web开发中,HTTP协议至关重要,无论构建Web应用还是API开发,都需要熟练掌握HTTP请求与响应处理。本文从C#角度出发,介绍HTTP基础知识,包括请求与响应结构,并通过`HttpClient`库演示如何发送GET请求及处理响应,同时分析常见错误并提供解决方案,助你更高效地完成HTTP相关任务。
86 2
|
1月前
|
存储 缓存 监控
HTTP:强缓存优化实践
HTTP强缓存是提升网站性能的关键技术之一。通过精心设计缓存策略,不仅可以显著减少网络延迟,还能降低服务器负载,提升用户体验。实施上述最佳实践,结合持续的监控与调整,能够确保缓存机制高效且稳定地服务于网站性能优化目标。
49 3
|
3月前
|
移动开发 JavaScript 前端开发
"解锁axios GET请求新姿势!揭秘如何将数组参数华丽变身,让你的HTTP请求在云端翩翩起舞,挑战技术极限!"
【8月更文挑战第20天】二维码在移动应用中无处不在。本文详述了在UniApp H5项目中实现二维码生成与扫描的方法。通过对比插件`uni-app-qrcode`和库`qrcode-generator`生成二维码,以及使用插件和HTML5 API进行扫描,帮助开发者挑选最佳方案。无论是即插即用的插件还是灵活的JavaScript实现,都能满足不同需求。
38 0
|
5月前
|
程序员 API 开发者
Socket与HTTP协议的实践
【6月更文挑战第4天】本文介绍了Python中的网络编程,包括Socket编程和基于HTTP协议的实践。Socket编程是网络通信的基础,Python的`socket`模块简化了其使用。文中展示了服务器和客户端的简单示例,以及如何通过多线程处理多个客户端连接。另外,文章讨论了HTTP协议,推荐了`requests`库,并给出了发送GET和POST请求的例子。最后,总结了Socket编程和HTTP协议在网络编程中的应用及其在Web开发和API交互中的重要性。
66 5
|
5月前
|
编解码 自然语言处理 算法
技术心得:前端学HTTP之字符集
技术心得:前端学HTTP之字符集
38 0
|
5月前
|
缓存 开发框架 网络协议
必知的技术知识:HTTP协议和SOCKS5协议
必知的技术知识:HTTP协议和SOCKS5协议
|
6月前
|
Go
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
122 4
|
6月前
|
前端开发 API UED
AngularJS的$http服务:深入解析与进行HTTP请求的技术实践
【4月更文挑战第28天】AngularJS的$http服务是核心组件,用于发起HTTP请求与服务器通信。$http服务简化了通信过程,通过深入理解和实践,能构建高效、可靠的前端应用。

热门文章

最新文章