Android优化篇|网络预连接

作者:苍耳叔叔

一个示例

前后分别去请求同一个域名下的接口,通过 Charles 抓包,可以看到 Timing 下面的时间:

  • 第二次请求时,DNS、Connect 和 TLS Handshake 部分都是 -,说明没有这部分的耗时,对比第一次请求的这三个部分,节省了 1 + 35 + 97 = 133ms
  • 当然第一次请求的 Request 和 Response 的 Size 比第二次要大一丢丢,且 Speed 低一些,忽略这些差异,在其他条件都一致的情况下,第二次请求比第一次请求能快 133ms。

第一次

第二次

这就是 http(s) 的连接复用。

连接复用

在此之前先简单复习一下发起网络 Request ->收到 Response 的粗略过程:

  1. 客户端发起网络请求
  2. 通过 DNS 服务解析域名,获取 IP 地址(一般是 UDP 协议)
  3. 建立 TCP 连接(三次握手)
  4. 建立 TLS 连接(Https)
  5. 发送网络请求 Request
  6. 服务器接收 Request 到后,执行逻辑并返回 Response
  7. 关闭 TCP 连接(四次挥手)

通过连接复用,上面的 2、3、4 步都不需要重新走了。使用 RTT 来定义这个时长,RTT(Round-Trip Time, 往返时间) 是网络请求从起点到目的地然后再回到起点所花费的时长。那么节省的时间是:

  • DNS 一般使用 UDP 协议,最近重新复习了下 DNS 的内容,如果 DNS 响应报文的长度大于 512 字节,则会使用 TCP 协议。事实上,很多 DNS 服务器进行配置时,也仅支持 UDP。因此这一步可以看成节省了 1 个 RTT。
  • 建立 TCP 连接,三次握手,需要 2 个 RTT。
  • 建立 TLS 连接,根据 TLS 版本,有不同的 RTT。

HTTP1.1 版本开始默认就是持久连接,可以复用,通过在报文头部加上 Connection:Close 来关闭连接。另外空闲的持久连接也可以随时被关闭,即使不发送 Connection:Close,也不意味着服务器连接永远保持打开。

预连接

常用的网络框架如 OkHttp 等,都支持 HTTP1.1 和 HTTP2 的功能,那也支持连接复用。

我们可以利用这个机制来做一个预连接,比如说在 APP 闪屏等待时,预先建立起关键页面域名的连接,这样在用户进入相应页面后可以更快的获取到网络请求结果,提升用户体验。

可以简单的对域名链接提前发起一个 HEAD 请求(没有Body),这样就能提前建立好连接,下次同域名的请求可以直接复用。

private val client by lazy { OkHttpClient() }btn.setOnClickListener {// 正式请求launch(Dispatchers.IO) {request()}
}// 预连接
launch(Dispatchers.IO) {preRequest()
}fun preRequest() {val request = Request.Builder().head().url("xxx").build()client.newCall(request).execute()
}fun request() {val request = Request.Builder().get().url("xxx/yyy").build()client.newCall(request).execute()
}

可以抓包看到首次进入时发送的 head 请求和实际上点击发送的 get 请求:

预连接

正式请求

可以看到正式请求时,确实少了上述三个步骤的耗时。还可以分别看下 Connection 和 TLS 的信息:

预连接

正式请求

能看出来正式请求时,这俩是复用的(关注 TLS 的 Session Resumed 和 Connection 的 Server Connection 部分)。

另外 OkHttp 中有个 ConnectionPool 连接池,在使用 Connect 连接时,会优先复用已有的连接,无可用时才创建新连接。连接池里容纳的连接数是限定的(貌似默认是 5 个),如果业务比较复杂,请求比较多的话,可能会导致连接池占满,这样就会释放之前做好的预连接。因此一个比较简单的方式就是适当调大连接池的容量和超时时间。

总结

通过 http(s) 的连接复用机制,我们可以考虑使用预连接来优化 APP 中某些场景的网络请求速度,这需要我们根据实际业务场景以及服务器压力来判断是否进行预连接。

另外我们可以适当调大连接池的容量和超时时间,由于连接是双向的,即使客户端把 Connection 一直保留,服务端也会根据实际连接数量和时长来自动关闭连接的,所以调大连接池一般不会增大服务器压力。

预连接的效果实际和服务器配置有关,如果服务器把连接超时设置得很小,那每次请求可能都需要重新建立连接,这样客户端的预连接会失效,且服务器也需要不断创建和销毁 TCP 连接而浪费更多资源;如果服务器把连接超时设置得很大,那之前的连接长时间都不会释放,导致服务器服务的并发数受到影响,影响新的请求。因此调优需要多端协调,综合考虑

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/52742.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大麦订单生成器 大麦一键生成订单

后台一键生成链接,独立后台管理 教程:修改数据库config/Conn.php 不会可以看源码里有教程 下载源码程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

使用langchain与你自己的数据对话(四):问答(question answering)

之前我已经完成了使用langchain与你自己的数据对话的前三篇博客,还没有阅读这三篇博客的朋友可以先阅读一下: 使用langchain与你自己的数据对话(一):文档加载与切割使用langchain与你自己的数据对话(二):向量存储与嵌入使用langc…

opencv-34 图像平滑处理-2D 卷积 cv2.filter2D()

2D卷积是一种图像处理和计算机视觉中常用的操作,用于在图像上应用滤波器或卷积核,从而对图像进行特征提取、平滑处理或边缘检测等操作。 在2D卷积中,图像和卷积核都是二维的矩阵或数组。卷积操作将卷积核在图像上滑动,对每个局部区…

百度智能云“千帆大模型平台”最新升级:接入Llama 2等33个模型!

今年3月,百度智能云推出“千帆大模型平台”。作为全球首个一站式的企业级大模型平台,千帆不但提供包括文心一言在内的大模型服务及第三方大模型服务,还提供大模型开发和应用的整套工具链,能够帮助企业解决大模型开发和应用过程中的…

【云原生】Docker中容器管理常用所有命令

1.docker 容器创建流程 2.容器运行本质 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 创建容器基本选项:--name:为容器命名 -i:交互式创建容器 -d:后台创建容器 -t:为容器分配伪终端 Docker 容器存在的意义就是为…

DP-GAN-生成器代码

首先看一下数据生成: 在预处理阶段会将label经过ont-hot编码转换为35个通道,即每个通道都是由(0,1)组成。 在train文件中,对生成器和判别器分别进行更新,根据loss的不同,分别计算对于的损失&a…

【element-ui】form表单初始化页面如何取消自动校验rules

问题描述:elementUI表单提交页面,初始化页面是获取接口数据,给form赋值,但是有时候这些会是空值情况,如果是空值,再给form表单赋值的话,页面初始化时候进行rules校验会不通过,此时前…

Java阶段五Day21

Java阶段五Day21 文章目录 Java阶段五Day21问题解析rocketmq清空数据 linux学习背景什么是linux系统虚拟机介绍启动 虚拟机linux虚拟机网络的问题 linux系统的基础命令命令提示符命令格式pwd指令ls指令cd指令mkdirtouch指令cp指令rm指令mv指令cat指令tail指令 文本编辑器vim操作…

【MySQL】表的约束

本期博客我们来搞定MySQL中对表的常用约束 目录 一、约束的概念 二、常用约束 2.1 非空约束 2.2 默认值 2.3 列描述 2.4 zerofill 2.5 主键 2.5.1 创建主键 2.5.2 删除表中的主键 2.5.3 追加主键 2.5.4 复合主键 2.5.5 主键使用实例演示 2.6 自增长 2.7 唯一键 …

Vue3_语法糖—— <script setup>以及unplugin-auto-import自动引入插件

<script setup>import { ref , onMounted} from vue;let obj ref({a: 1,b: 2,}); let changeObj ()>{console.log(obj)obj.value.c 3 //ref写法}onMounted(()>{console.log(obj)})</script> 里面的代码会被编译成组件 setup() 函数的内容。 相当于 <…

【MYSQL】DataGrip连接linux本地mysql失败:Connection refused

防火墙需要开放3306端口 sudo ufw allow 3306 要么就把防火墙关了&#xff1a; sudo ufw disablemysql开放连接 记住你的密码 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password by 123456;修改配置文件 sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf这个…

企业网盘解析:高效的企业文件共享工具

伴随着信息技术的发展&#xff0c;越来越多的企业选择了基于云存储的企业网盘来进行企业数据存储。那么企业网盘是什么意思呢&#xff1f; 企业网盘是什么意思&#xff1f; 企业网盘&#xff0c;又称企业云盘&#xff0c;顾名思义是为企业提供的网盘服务。除了服务对象不同外&…