做网络优化,首先我们要这个流程有一定的认识,大致流程如下:
-
生成请求行
-
查找强缓存(不一定都有)
-
DNS域名解析(找到Host主机IP)
-
建立TCP连接(三次握手)
-
发送HTTP请求
-
接收HTTP响应
-
断开连接(四次挥手)
简单回顾之后,就可以由点及面,各个击破了~
目录
GRPC( A high-performance, open-source universal RPC framework)
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<InetAddress> {
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,就是这个服务是收钱的。
CDN 缓存静态资源
缓存常见的图片、JS、CSS 等静态资源。
不用域名,用 IP 直连
省去 DNS 解析过程,DNS 全名 Domain Name System,解析意指根据域名得到其对应的 IP 地址。首次域名解析一般需要几百毫秒,可通过直接面向 IP 而非域名请求,节省掉这部分时间,同时可以预防域名劫持等带来的风险。当然为了安全和扩展考虑,这个 IP 可能是一个动态更新的 IP 列表,并在 IP 不可用情况下通过域名访问。
连接池复用
keep-alive HTTP 协议里有个 keep-alive,HTTP1.1默认开启,一定程度上缓解了每次请求都要进行TCP三次握手建立连接的耗时。原理是请求完成后不立即释放连接,而是放入连接池中,若这时有另一个请求要发出,请求的域名和端口是一样的,