Android优化篇|网络预连接

news2024/10/2 18:18:42

作者:苍耳叔叔

一个示例

前后分别去请求同一个域名下的接口,通过 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.coloradmin.cn/o/836212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# 控制台彩色深度打印 工具类

文章目录 前言Nuget 环境安装代码使用打印结果 总结 前言 有时候我们想要靠打印获得程序信息,因为Dubeg模式需要一点一点断点进入进出,但是我们觉得断点运行实在是太慢了,还是直接打印后找结果会好一点。 Nuget 环境安装 想自己写的话可以看…

unity tolua热更新框架教程(1)

git GitHub - topameng/tolua: The fastest unity lua binding solution 拉取到本地 使用unity打开,此处使用环境 打开前几个弹窗(管线和api升级)都点确定 修改项目设置 切换到安卓平台尝试打包编译 设置包名 查看报错 打开 屏蔽接口导出 重新生成 编译通过 …

FineReport常用功能

不分页显示数据 参见:https://help.fanruan.com/finereport/doc-view-328.html?source4 列数多时,所有列不能在一页显示,可在URL后增加如下参数,添加模版时,可以作为模版参数进行设置: 分页预览模式&am…

orangepi 4lts ubuntu安装RabbitMQ

4lts的emmc 系统安装选文件系统格式 ext4 需先安装erlang: sudo apt install erlang 安装RabbitMQ: sudo apt install rabbitmq-server - 添加用户以便远程访问: - 账号密码都是admin: sudo rabbitmqctl add_user admin admin -sudo rabbitmqct…

C 语言高级2-多维数组,结构体,递归操作

1. 多维数组 1.1 一维数组 元素类型角度:数组是相同类型的变量的有序集合内存角度:连续的一大片内存空间 在讨论多维数组之前,我们还需要学习很多关于一维数组的知识。首先让我们学习一个概念。 1.1.1 数组名 考虑下面这些声明&#xff1…

钉钉微应用

钉钉微应用 在做钉钉微应用开发的时候,遇到了一些相关性的问题,特此记录下,有遇到其他问题的,欢迎一起讨论 调试工具 当我们基于钉钉开发微应用时,难免会遇到调用钉钉api后的调试,这个时候可以安装eruda…

笔记本WIFI连接无网络【实测有效解决方案,不用重启电脑】

笔记本Wifi连接无网络实测有效解决方案 问题描述: 笔记本买来一段时间后,WIFI网络连接开机一段时间还正常连接,但是过一段时间显示网络连接不上解决方案: 1.编写网络重启bat脚本,将以下内容写到文本文件,把…

使用 FastGPT 构建高质量 AI 知识库

作者:余金隆。FastGPT 项目作者,Sealos 项目前端负责人,前 Shopee 前端开发工程师 FastGPT 项目地址:https://github.com/labring/FastGPT/ 引言 自从去年 12 月 ChatGPT 发布以来,带动了一轮新的交互应用革命。尤其在…

【分布式系统】聊聊系统监控

对于分布式系统来说,出现故障的是常有的事情,如何在短时间内找到故障的原因,排除故障是非常重要的,而监控系统是就像系统的眼睛可以通过分析相关数据,进一步管理和运维整个分布式系统。 监控系统的的基本功能包含 全…

Java02-迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类

目录 什么是遍历? 一、Collection集合的遍历方式 1.迭代器遍历 方法 流程 案例 2. foreach(增强for循环)遍历 案例 3.Lamdba表达式遍历 案例 二、数据结构 数据结构介绍 常见数据结构 栈(Stack) 队列&a…

移远通信携手产业合作伙伴率先完成RedCap端网兼容性现网测试

近日,移远通信与中国联通携手,基于搭载高通骁龙X35平台的移远RedCap模组RG255C-CN,在上海嘉定率先完成3.5GHz、2.1GHz、900MHz 中国联通5G全频段 RedCap端网兼容性现网测试,为5G RedCap商用部署奠定了坚实基础。 本次5G RedCap外场…

【Python:参数解析器argparse】对命令行参数进行解析

常用的流程如下: 1、先创建一个解析器: parser argparse.ArgumentParser(description"...")2、为解析器增加参数,包括name、默认值、帮助信息等 parser.add_argument(name "", default ..., help ...)name前面可以…

CS5366+VL171母座正反插HDMI(CS5466也可搭配)国产芯片TYPEC方案设计 ASL电路原理图 集睿致远+威锋设计

VL171是威锋芯片,可搭配ASL集睿致远CS5366设计TypeC母座正反插转HDMI高清投屏方案,CS5366是2lane 芯片,支持4K60HZ,是CS5266的升级版,CS5366设计拓展坞方案可以替代CS5266携带快充100W的PD和US,多口HUB也不在话下,而画面的刷新率和…

在IDEA同一个窗口中同时打开多个独立项目

文章说明 本文主要说明如何在Intellij Idea中同时打开多个独立的Maven项目。 我在使用idea的时候,由于自己负责了很多项目,经常要在不通的代码之间切换来切换去。然后搜索代码的时候也只能搜到当前打开的这个项目。因为这个原因,一些小项目…

利用prophet实现时间序列数据结果预测及对预测数据进行年度趋势和月度值分解

第一部分:prophet的介绍 选取一段chatgpt对该插件的解释,如下: Prophet(预言家)是由Facebook开发的开源时间序列分析工具,旨在提供一个简单而强大的框架,用于预测时间序列数据。Prophet的设计目…

使用中间人攻击的arp欺骗教程

文章目录 前言一、查看网络接口配置第 1 步:从受害者处获取 IP 配置第 2 步:在 Linux 中打开数据包转发第 3 步:使用 arpspoof 将包重定向到您的计算机步骤4:拦截来自路由器的包裹步骤5:从目标的浏览器历史记录中嗅探图…

LeetCode 热题 100 JavaScript--102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 示例 2: 输入:root [1…

Java 线程基础

volatile happens-before原则 1、单一线程原则 在一个线程内,在程序前面的操作线性发生于后面的操作 2、管程锁定原则 一个unlock操作先行发生于后面对同一个锁的lock操作 3、volatile变量原则 对一个volatile变量的写操作先行发生于后面对变量的读操作 4、线…

资深测试经验总结,APP测试-关键点整理,少走3年的弯路...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 APP测试它的关键点…

LeetCode--HOT100题(16)

目录 题目描述:238. 除自身以外数组的乘积(中等)题目接口解题思路代码 PS: 题目描述:238. 除自身以外数组的乘积(中等) 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等…