机关网站建设前期准备工作,wordpress建站腾讯云,app平台搭建需要多少钱,贵阳优化网站建设作者#xff1a;苍耳叔叔 一个示例
前后分别去请求同一个域名下的接口#xff0c;通过 Charles 抓包#xff0c;可以看到 Timing 下面的时间#xff1a;
第二次请求时#xff0c;DNS、Connect 和 TLS Handshake 部分都是 -#xff0c;说明没有这部分的耗时#xff0c;… 作者苍耳叔叔 一个示例
前后分别去请求同一个域名下的接口通过 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全家桶篇内含Composehttps://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