Android优化篇|网络预连接
作者:苍耳叔叔
一个示例
前后分别去请求同一个域名下的接口,通过 Charles 抓包,可以看到 Timing 下面的时间:
- 第二次请求时,DNS、Connect 和 TLS Handshake 部分都是
-,说明没有这部分的耗时,对比第一次请求的这三个部分,节省了1 + 35 + 97=133ms。 - 当然第一次请求的 Request 和 Response 的 Size 比第二次要大一丢丢,且 Speed 低一些,忽略这些差异,在其他条件都一致的情况下,第二次请求比第一次请求能快 133ms。
第一次

第二次

这就是 http(s) 的连接复用。
连接复用
在此之前先简单复习一下发起网络 Request ->收到 Response 的粗略过程:
- 客户端发起网络请求
- 通过 DNS 服务解析域名,获取 IP 地址(一般是 UDP 协议)
- 建立 TCP 连接(三次握手)
- 建立 TLS 连接(Https)
- 发送网络请求 Request
- 服务器接收 Request 到后,执行逻辑并返回 Response
- 关闭 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
相关文章:
Android优化篇|网络预连接
作者:苍耳叔叔 一个示例 前后分别去请求同一个域名下的接口,通过 Charles 抓包,可以看到 Timing 下面的时间: 第二次请求时,DNS、Connect 和 TLS Handshake 部分都是 -,说明没有这部分的耗时,…...
pyspark使用XGboost训练模型实例
遇到一个还不错的使用Xgboost训练模型的githubhttps://github.com/MachineLP/Spark-/tree/master/pyspark-xgboost 1、这是一个跑通的代码实例,使用的是泰坦尼克生还数据,分类模型。 这里使用了Pipeline来封装特征处理和模型训练步骤,保存为…...
完整模型的训练套路
从心所欲 不逾矩 天大地大 皆可去 一、官方模型的初使用 使用VGG16模型 VGG模型使用代码示例: import torchvision.models from torch import nndataset torchvision.datasets.CIFAR10(/cifar10, False, transformtorchvision.transforms.ToTensor())vgg16_true …...
PtahDAO:全球首个DAO治理资产信托计划的金融平台
金融科技是当今世界最具创新力和影响力的领域之一,区块链技术作为金融科技的核心驱动力,正在颠覆传统的金融模式,为全球用户提供更加普惠、便捷、安全的金融服务。在这个变革的浪潮中,PtahDAO(普塔道)作为全…...
从零搭建一个react + electron项目
最近打算搭建一个react electron的项目,发现并不是那么傻瓜式 于是记录一下自己的实践步骤 通过create-react-app 创建react项目 npx create-react-app my-app 安装electron依赖 npm i electron -D暴露react项目的配置文件(这一步看自己需求,…...
MATLAB /Simulink 快速开发STM32(使用st官方工具 STM32-MAT/TARGET),以及开发过程
配置好环境以后就是开发: stm32cube配置芯片,打开matlab添加ioc文件,写处理逻辑,生成代码,下载到板子中去。 配置需要注意事项: STM32CUBEMAX6.5.0 MABLAB2022BkeilV5.2 Matlab生成的代码CTRLB 其中关键的…...
LeetCode 热题 100 JavaScript--102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 示例 2: 输入:root [1…...
常见Git命令
Git常见命令 1. 添加单个文件 git add a.txt2. 添加多个文件 git add a.txt b.txt c.txt3. 添加(commit)修改,此时修改还未push到服务器上 git commit -m "修改了a.txt内容"4. 提交(push)修改,此时修改会同步到服务器上 git push5. 查看当…...
在C语言中调用汇编语言的函数
在C语言中调用汇编文件中的函数,要做的主要工作有两个: 一是在C语言中声明函数原型,并加extern关键字; 二是在汇编中用EXPORT导出函数名,并用该函数名作为汇编代码段的标识,最后用mov pc, lr返回。然后&a…...
Delphi Professional Crack,IDE插件开发和扩展IDE
Delphi Professional Crack,IDE插件开发和扩展IDE 构建具有强大视觉设计功能的单源多平台本机应用程序。 Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Professional适合个人开发人员和小型团队构建…...
程序框架-公共MONO模块
作用:让没有继承MONO的类可以开启协程,可以update更新,可以统一管理update MonoController脚本继承MonoBehaviour使得脚本过场不移除,并通过UnityAction可以添加多个函数(多播委托),实现Update…...
采用鲁棒随机森林实现的流异常检测:Python应用的一种新型机器学习方法
在数字化和互联网化日益普遍的现代社会,处理海量的网络流量数据是网络安全分析中不可或缺的一部分。流异常检测是一种重要的技术,用于发现可能的安全威胁,例如:网络攻击、恶意行为和系统故障等。随机森林是一种普遍用于解决这类问题的机器学习算法。在本文中,我们将介绍一…...
缓存友好在实际编程中的重要性
引入 当CPU执行程序时,需要频繁地访问主存储器(RAM)中的数据和指令。然而,主存储器的访问速度相对较慢,与CPU的运算速度相比存在显著差异,每次都从主存中读取数据都会导致相对较长的等待时间,从…...
uni-ajax网络请求库使用
uni-ajax网络请求库使用 uni-ajax是什么 uni-ajax是基于 Promise 的轻量级 uni-app 网络请求库,具有开箱即用、轻量高效、灵活开发 特点。 下面是安装和使用教程 安装该请求库到项目中 npm install uni-ajax编辑工具类request.js // ajax.js// 引入 uni-ajax 模块 import ajax…...
MYSQL进阶-事务
1.什么是数据库事务? 事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执 行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上 的一组操作,要么都执行,要么都不执行。 事务…...
python 常见数据类型和方法
不可变数据类型 不支持直接增删改 只能查 str 字符串 int 整型 bool 布尔值 None None型特殊常量 tuple 元组(,,,)回到顶部 可变数据类型,支持增删改查 list 列表[,,,] dic 字典{"":"","": ,} set 集合("",""…...
a-date-picker报错TypeError: date4.locale is not a function
问题描述 使用日期选择器,数据从后端获得,再赋值给a-date-picker做数据回显,遇到这个报错,排错后定位到a-date-picker组件本身接收数据的问题。 如果使用了dayjs或moment库来处理时间字符串,并且使用.format对时间数据…...
LNMP安装
目录 1、LNMP简述: 1.1、概述 1.2、LNMP是一个缩写词,及每个字母的含义 1.3、编译安装与yum安装差异 1.4、编译安装的优点 2、通过LNMP创建论坛 2.1、 安装nginx服务 2.1.1、关闭防火墙 2.1.2、创建运行用户 2.1.3、 编译安装 2.1.4、 优化路…...
matplotlib绘图风格
文章目录 绘图风格测试代码默认和mpl风格复制风格seaborn风格 绘图风格 matplotlib功能强大,可以定制各种绘图要素,以满足个性化的绘图需求,而更换绘图风格也十分便捷,一个matplotlib.style.use函数轻松搞定,而可用的…...
【初级教程】Appium 启动应用 log 日志分析
刚开始学习 appium 时,老师给我布置了 appium 启动应用 log 分析的作业。由于工作比较忙,再者自己想先动手用 appium 写个公司的 app 的 UI 测试(目前简单的框架基本完成,在不断完善用例管理中)。写这篇文章是为了完成…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
