小虾:emmmmmmm,这不是怕被你打击吗。
面试官:ok,看来是有备而来,那么我们今天聊聊网络优化咋做吧。
小虾:我大意了,没有闪。老头子,你不讲武德,我奉劝你耗子尾汁。
相信大家在面试的时候可能会被问到这个问题。今天我其实就是讲述下我知道的一些简单的优化方式,可以帮助大家在面试的过程中得到点基础分数。
我们先从最简单,大家比较容易了解到的讲起。
DNS优化
一个Http请求在建立Tcp连接的过程中,肯定会产生一次DNS,那么我们是不是可以通过内存缓存的方式,通过一个HashMap持有这个Host的IP,当下次发起Tcp连接的时候,我们就可以用直接用内存中的这个Ip,而不需要再去走一遍Dns服务了。
这个时候你肯定会问我,你这个不是搞我吗,这可怎么改呀?
如果你的网络层用的是OkHttp的话,Okhttp在封装的时候就已经考虑到这个部分了,其内部提供了Dns的接口,可以让外部在构造Client的时候传入。
class HttpDns : Dns {
private val cacheHost = hashMapOf<String, InetAddress>()
override fun lookup(hostname: String): MutableList {
if (cacheHost.containsKey(hostname)) {
cacheHost[hostname]?.apply {
return mutableListOf(this)
}
}
return try {
InetAddress.getAllByName(hostname)?.first()?.apply {
cacheHost[hostname] = this
}
mutableListOf(*InetAddress.getAllByName(hostname))
} catch (e: NullPointerException) {
val unknownHostException =
UnknownHostException(“Broken system behaviour for dns lookup of $hostname”)
unknownHostException.initCause(e)
throw unknownHostException
}
}
}
这里可以稍微给大家展开下,LocalDns是不可以被信任的,经常会有运营商会搞一些奇奇怪怪的Dns拦截,导致大家收到的请求是运营商所缓存的(目的是为了省流量),所以阿里腾讯等都有自己对外输出的HttpDns的服务。这个服务可以帮助大家找到真实准确的Host的Ip,就是这个服务是收钱的。
如果你是个IOS开发人员,那么你一定要注意SNI(Server Name Indication),一个IP对应多个多个Https证书的问题。
https://blog.csdn.net/firefile/article/details/80532161
CacheControl
Http请求在1.1阶段就引入了CacheControl了,通过CacheControl可以让后端直接控制请求内容的缓存策略。所以还有比缓存更简单粗暴的网络优化方式吗?
在http中,控制缓存开关的字段有两个:Pragma 和 Cache-Control。
通过图片简单的介绍下一些缓存参数。
如果说一句不负责任的话,这个只要后端大佬开启CacheControl就好了呀,原生网络库本来就支持的。
当然后端大佬一般都不是特别愿意,其实各位安卓也可以通过添加OkHttp拦截器的方式给网络请求添加一个统一的CacheControl,当然如果你有定制化的需求肯定还是要自己开发的,细节大家可以参考下这个仓库。https://github.com/yale8848/RetrofitCache
HTTP协议规格说明定义ETag为“被请求变量的实体值”。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:ETag:"50b1c1d4f775c61:df3"客户端的查询更新格式是这样的:If-None-Match : W / "50b1c1d4f775c61:df3"如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。测试Etag主要在断点下载时比较有用。
而我们只要使用了CacheControl,就可以用到ETag, 如果当数据内容没有发生变更的情况下,就不会传输数据,这样也可以给大家略微优化下你们的Api请求。
Http 1.0 - 1.1 - 1.X - 2.0
以下所有内容均来自网络 HTTP1.0、HTTP1.1 和 HTTP2.0 的区别。
https://www.cnblogs.com/heluan/p/8620312.html
当然我们还可以让后端升级接口协议版本,这个可以明显提升你请求响应性能。
-
长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection:keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
-
header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
-
新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
-
多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别?
HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
好了,下面要开始真的进入牛逼的东西了,前文你肯定以为我是个大水逼,复制黏贴。
GRPC( A high-performance, open-source universal RPC framework)
不知道各位有没有听说过一个都市怪谈,字节的网络库优化有多厉害多厉害,网络底层采用的是Webview底层的Chromium的网络库,在弱网情况下对于api的优化啥的,巴拉巴拉…
Cronet是Chromium网络引擎对不同操作系统做的封装,实现了移动端应用层、表示层、会话层协议,支持HTTP1/2、SPDY、QUIC、WebSocket、FTP、DNS、TLS等协议标准。支持Android、IOS、Chrome OS、Fuchsia,部分支持Linux、MacOS、Windows桌面操作系统。实现了Brotli数据压缩、预连接、DNS缓存、session复用等策略优化以及TCP fast open等系统优化。本文内容基于Chromium 75版本。
字节用的就是Chrome的cronet网络库(顺便展开下,cronet同时支持ios,android,前端)。而由于grpc协议的问题,所以传输内容直接使用的protobuf格式,所以其不仅仅是网络层上的优化,同时由于流能直接转化成实体类,同时也减少了可序列化的时间。
https://github.com/grpc/grpc-java
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!