转自:掘金 - 究极逮虾户

https://juejin.cn/post/6896302142542315533

1  如何优化一个网络请求呢?

相信大家在面试的时候可能会被问到这个问题。今天我其实就是讲述下我知道的一些简单的优化方式,可以帮助大家在面试的过程中得到点基础分数。

我们先从最简单,大家比较容易了解到的讲起。

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,就是这个服务是收钱的。

如果你是个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

当然我们还可以让后端升级接口协议版本,这个可以明显提升你请求响应性能。

  1. 长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection:keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。

  2. header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。

  3. 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

  4. 多路复用(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

protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

但是正常的网络框架基本都使用了Retrofit+Okhttp,而且大家都已经使用的很习惯了,所以我大胆的猜测,字节其实应该用OkHttp桥接了cronet。所以这样基本就能无缝桥接当前已有的网络库了。

由GRRC升级QUIC

QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议。在2016年11月国际互联网工程任务组(IETF)召开了第一次QUIC工作组会议,受到了业界的广泛关注。这也意味着QUIC开始了它的标准化过程,成为新一代传输层协议

其实整个QUIC协议(Http3.0协议)本来就是谷歌写的,所以谷歌的Cronet本身就支持这也是正常的。

我其实之前就特地去查过OKHttp支持的协议内容,当前还是只停留在2.0阶段,主要就还是因为当前的Connection写的太好了,而且需要把Tcp直接更换成Udp,所以迟迟没有更新3.0协议的支持。

所以各位如果想从协议层去做对应的优化,那么可能OkHttp带给大家的应该还是无尽的等待了。

2 还能干吗?

其实优化方面我的大概的姿势点就这么多了,但是我们可以考虑从监控方面的角度去再重新审视这个话题哦。

客户端请求从发起到网关实际接收到,其实中间有很复杂的链路,简单的说,OKhttp内也走过了这么多个拦截器了。但是当一个线上用户反馈这个界面怎么刷出来的这么慢的情况下,我们以后端网关开始作为请求的开始节点,就会出现难以定位真实问题的情况。

基于OkHttp的网络监控

我们是不是可以考虑把整个api发起到结束进行监控,从而可以方便线上去监控一个Api真实的发起到结束的状况呢?我们先简单的把一个请求的节点拆分下。我要盗图了。

参考数据深入理解OkHttp3:(七)事件(Events)https://www.pianshen.com/article/8120939/

基于OKHttp提供的EventListener,我们就可以对于一个请求发起到最后的各个节点进行监控,之后上报日志数据,这样在后续的撕逼过程中,其实就可以做到有理有据,有话可说,你真的慢了。

总结

这篇文章基本就纯粹是为了各位应付面试用的,也算是我对于Android网络优化的一些简单的总结吧。其实中间能展开的内容也还是有的,就是需要各位自己去摸一摸了。

PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。

大家一起在评论区聊聊呗~

Android网络优化攻略,简单了解一下?相关推荐

  1. Android学习攻略:手把手教你循序渐进地学习Android知识

    前言 如果你也学习Android,那么你大概率会看过我的文章.经常有读者给我留言:"该怎么学习Android?"."日常学习Android的方法是什么". 所以 ...

  2. 倩女幽魂2服务器维护怎么抢先进,倩女幽魂2宁远觉华战役攻略:简单粗暴抢分秘诀分享...

    倩女幽魂2宁远觉华战役攻略:简单粗暴的抢分秘诀. 在宁远觉华这种大型人数极多的PVP战役里,抢分才是王道!玩家分享独门抢分秘诀,你值得拥有! 首先,我们分两个战场讲. 宁远城 1.装备不给力,怎么办? ...

  3. android游戏手柄,没手柄也不怕 键盘玩Android游戏攻略

    越来越多的朋友开始在手机等移动设备上享受游戏的乐趣,可不得不说用手指在触屏上玩游戏总有那么点不爽,于是乎,有玩家开始琢磨手机游戏新的玩法,为手机配上手柄(如下图),这其中既有专用的,也有将其他游戏平台 ...

  4. android游戏攻略,安卓手机游戏攻略

    攻略 独奏骑士70层如何通关 在独奏骑士中有很多的特色玩法,其中一个就是爬塔玩法,在这里有多个关卡,70层就是其中一关,也是比较复杂的一关,下面就跟着小编一起来看看70层通关方法吧!独奏骑士70层通 ...

  5. WM平台玩转Android全攻略

    Android系统目前大行其道,flowermix也把玩过一段时间的G2,被Android系统的开放性和丰富的软件所吸引(我是重度测试控╮( ̄▽ ̄")╭ ). 相信大家早就看到过很多关于Wi ...

  6. flutter开发工具,2020年最全Android面试攻略

    摘要 开篇之前,首先说一下,大神就别点进来了.小编只是尘世间一个迷途小开发,二流程序员. 这篇文章并不像其他面经一样金光闪闪,只是一个二流Android攻城狮在市场的大潮之下,用一个月时间面试+复习+ ...

  7. Android出海攻略(一):Google Play 上架扫盲

    由于某些 不(xin)可(zhi)描(du)述(ming) 的原因,缺少"武林盟主"的国内Android市场一直比较混乱,应用分发.应用质量管控.权限管控.隐私管控 等各方面都不被 ...

  8. Android面试攻略

    文章背景 在外界看来IT是一个"高薪"的行业,都羡慕不已,熟不知IT也是一个苦逼的行业,每天加班加点,时刻用生命在写代码啊,导致许多程序猿和程序媛们都找不到对象,好不容易有个家庭的 ...

  9. Android8.thumbnails,Android Thumbnail 攻略

    本文简单研究一下MediaScanner生成及保存thumbnail的方式,并给出代码快速查询图片的thumbnail, 希望可以抛块儿砖,引出一大堆玉来~ 1. 手动执行Dev Tools /Med ...

最新文章

  1. 领导应该怎么当?盯目标、抓计划、管时间、做农夫、当仆人……
  2. 远程java接口说明
  3. 一文读懂区块链上的隐私与监管问题
  4. 必要商城MySQL开发规范
  5. C语言僵尸进程,C/C++网络编程8——多进程服务器端之销毁僵尸进程
  6. spring更新后 外层事务查不到_再深一点:面试工作两不误,源码级理解Spring事务...
  7. 和氟西汀类似的备注_撒狗粮:可爱又霸气的给男朋友的微信备注
  8. html中的异步请求数据格式,解决layui中table异步数据请求不支持自定义返回数据格式的问题...
  9. layui弹出框php,layui中使用的一些弹出框
  10. 【转】C#中的弱事件:不同的解决方法
  11. ViewPager 简单实现左右无限滑动.
  12. 21天学通C语言-学习笔记(10)
  13. avr 运行 linux,linux(ubuntu9.04)安装avr编译环境
  14. PS的30个实用技巧大全
  15. [转载]JTree 编辑、删除、添加节点_-Chaz-_新浪博客
  16. CSS背景background和显示元素
  17. 算法-使用双指针遍历删除链表节点
  18. php 挂起一个请求一直执行,在后台运行进程挂起PHP pag
  19. python手机app开发_H5 手机 App 开发入门:技术篇
  20. pid温度控制c语言程序及仿真,pid算法温度控制c语言程序

热门文章

  1. JxlExcelUtil生成Excel供SFTP推送Java实现获取目录下最新的excel
  2. 预产期计算器在线计算生男生女计算机,预产期计算器生男生女
  3. java制作excel报表_java制作Excel报表简单易用(拿来即用)
  4. 队列的基本操作(全)
  5. win11怎么使用录屏功能?两个小技巧了解一下
  6. 程序人生-Hello’s P2P——哈尔滨工业大学计算机系统大作业
  7. 耳机插在电脑上只有按住接听键,才能正常听到声音怎么解决
  8. 全志D1-H芯片 如何移植 rtl8821cu wifi 驱动到 Linux-5.4内核?
  9. linux管理的救星,优秀SSH软件推荐:FinalShell SSH工具,服务器管理,远程桌面加速软件,支持Windows,Mac OS X,Linux
  10. java如何抛出异常_java中 方法中抛出异常处理方法