Cronet简介

Cronet是什么,引用官方的解释,如下:

Cronet is the networking stack of Chromium put into a library for use on mobile. This is the same networking stack that is used in the Chrome browser by over a billion people. It offers an easy-to-use, high performance, standards-compliant, and secure way to perform HTTP requests. Cronet has support for both Android and iOS. On Android, Cronet offers its own Java asynchronous API as well as support for the java.net.HttpURLConnection API. This document gives a brief introduction to using these two Java APIs.

解释出处:https://chromium.googlesource.com/chromium/src/+/master/components/cronet/README.md?autodive=0%2F%2F

大概的释义可以解释为以下几个方面

  • Cronet是一个对Chromium的网络模块的封装库
  • 支持android/iOS移动平台
  • 可以无缝对接到各个平台的常见网络库同时也拥有自己的API
  • 支持HTTP协议,同时支持QUIC协议

既然Cronet能够同时Http协议和QUIC协议,那么他是如何做出选择使用哪种协议进行通信的呢?

Cronet对HTTP和QUIC协议的选择原理分析

针对Cronet真正发起请求时采用的网络协议,其实没有太多相关资料给与解释。首先我先拿一个我们线上的事故来举例分析一下Cronet对网络协议的选择原理。

1. 线上事故

事故描述: 广东地区,线上突发报警,网络请求超时比例严重超过预订阀值?拉取用户日志发现,超时请求均是由于CDN调度问题,将广东的用户全部调度到了陕西的CDN节点上。但是奇怪的是日志显示DNS解析的CDN节点均在广东省,那为什么客户端会将请求全部打到陕西节点呢?具体日志如下:

  • 客户端dns解析结果均为14.152.86.35(广东),没有出现跨地域调用
  • 客户端实际建连的CDN IP为36.42.75.35(陕西),竟然是跨省调用

为什么会出现这种现象呢? 我们带着问题看一下Cronet的建连原理

2. Cronet建连协议选择原理

2.1 首次请求

此处的首次请求和后续请求均是指的相同域名下的请求

  • 1、首次请求,客户端发送正常的HTTP协议请求,此过程与正常HTTP请求的唯一区别是,携带了支持QUIC协议的信息,告诉Server端,Client支持QUIC请求

  • 2、Server端收到请求后,判断自身是否支持QUIC协议

  • 3-1、如果Server端支持QUIC协议,Server端直接在response header中添加一个响应头: alt-syc

    alt-syc携带的是什么信息呢?主要包含三部分信息

    • quic=ip:port 告诉客户端QUIC建连的IP和端口
    • ma=xxxxx 主要用来标识服务是否可用(是否在有效期)
    • v=xx,xx 标识Server端支持的QUIC版本
  • 3-2、如果Server端不支持QUIC协议,则直接按照HTTP协议返回,response header中不包含:alt-syc头部信息

2.2 第二次请求

  • 1、客户端第二次请求,Cronet网络库同时发出基于TCP的HTTP连接和基于UDP的QUIC连接
    • TCP连接基于正常的DNS解析进行建连
    • QUIC连接是基于第一次请求时Server端在alt-syc头信息中标注的ServerIP和端口号进行发起的,而不走DNS解析
  • 2、Server接收两种连接后均会做出反馈给客户端
  • 3、客户端等待两个连接的响应,Cronet会按照时间维度判断哪个连接首先建立成功。
    • 如果QUIC连接首先完成,则后续请求均走此QUIC连接;
    • 如果HTTP连接首先完成,则后续直接按照HTTP连接与Server通信;
2.3 总结

看完这两个过程,不难发现,Cronet创建QUIC连接时,其实是不依赖于本地DNS解析的,正常需要建立QUIC连接的IP和端口均是有Server端提前告知的,因此Cronet对HTTP和QUIC协议的选择可以归纳为以下几点:

  • 首次请求,基于DNS建立HTTP连接,并下发QUIC的建连信息
  • 第二次请求,采用竞速模式,以时间维度则其优。
  • QUIC建连时,不依赖本地DNS解析,而是按照Server下发信息进行建连

3. 线上事故原因分析

看完Cronet建连协议选择原理,再来分析一下此次线上事故:

  • 1、首先会发现确认,超时的请求建连IP均是跨地域的,并且和DNS解析结果严重不符,从这一点能够得出结论,此次网络请求是走的QUIC协议,也就是说QUIC连接竞速时获胜了
  • 2、既然是QUIC协议,那么此建连的IP就是Server端下发的和本地DNS解析结果无关,那么到这里就解释了为什么客户端会将请求全部打到跨域的节点上
  • 3、去找客户端首次请求,发现首次请求时,Server端下发的alt-syc头信息中的建连IP正是此跨域IP,因此可以定位到确实是CDN Server端将非最优的QUIC建连IP下发到了客户端。
  • 4、到这里就可以拿着证据正义凌然的去找CDN同学喝饮料了