三十三、安卓开发中针对网络编程做出的优化

概述

一次网络请求的操作,是从DNS解析开始,建立连接并发送数据到服务端,然后读取服务端返回的数据,最后释放连接。

DNS解析优化

安全方面

DNS指的是,域名解析,我们访问一个域名,实际上是访问的它对应的ip地址,DNS实际上就是 将域名解析成ip的过程。

DNS的过程之所以能够被劫持,是因为解析过程中,如果遇到了中间人劫持,就有可能返回给你一个 恶意的IP地址。

通常的解决方案是,HttpDps,它只是一个概念,并不是一个现成的开源库。它与传统DNS解析的区别在于,HttpDns会绕过运营商的DNS服务器,直接与DNS服务器80端口连接,有效防止域名劫持。

阿里云和腾讯云已经实现了这种功能,但是都是收费的,所以 PASS.

普通开发者可以用 七牛的免费Happy-DNS.

OkHttp已经预留了 dns设置的接口。

我们需要实现的是 上图中的loopUp接口,上面红框中的SYSTEM,是系统给我们默认的DNS解析器。

添加依赖库:

然后自己实现一个DNS的实现类:

最后将这个HttpDns设置给okhttp即可。

java 复制代码
OkHttpClient client = new OkHttpClient.Builder()
    .dns(new HttpDns())
    // 其他配置
    .build();

速度方面

DNS解析需要连接到 DNS服务器,服务器去帮我们查询具体的ip然后再给到我们,这个过程是会耗费一定时间的。

是不是每次都要去DNS服务器请求ip地址? 不一定吧。当http服务发布以后,ip地址很少会有大规模的变化。所以,我们可以缓存域名和ip的对应关系到本地,请求dps服务器之前,先看本地缓存,本地没有缓存再去走dns服务器。 这个也可以称为 IP直连方式,但是这种方式成本较高,我们需要在本地维护一套 域名IP对应机制,另外,HTTPS的访问要求证书绑定域名,在执行https请求时,客户端需要保存以及解析证书,这部分工作成本也较大。


如果我们正在请求一个 http请求时,如果网络设备切换路由,就有可能出现dns解析超时的情况。很久以后会抛出 UnknownHostException ,并且 okhttp 设置的超时时间对这种情况不起作用。

这种情况,可以在自定义DNS中做超时判断,

这里利用了 Java新特性中的Future,如果一个任务在一定时间内没有执行完毕,就抛出异常。

网络请求缓存优化

请求失败

当一个网络请求执行失败之后,将请求本身缓存在本地,稍后尝试重新发送。

请求成功

网络请求成功之后,将返回的数据以及请求用键值对的方式缓存在本地。下一次执行相同的请求,先展示缓存的数据,当新数据到来之后,再对比新旧数据,如果有差异,则展示新数据。

以下是一些示范(只是展示思想,不要照搬):

上图是利用的 dao.insertOrReplace(); dao指的是数据库的映射。 图中1处,将网络请求本身以及相关参数 设置到 httpDataCache对象中去, 图中2处,将缓存数据转化成json字符串,并设置到 httpDataCache 图中3处,将 httpDataCache 提交到 数据库。

数据库的结构如下:

而在网络层代码中,在执行网络请求之前,先尝试从数据库中取出 当前请求的缓存结果,展示在界面上,然后去请求网络,并且在请求成功之后,将 结果再次缓存。大概如下:

幂等性

当我们点外卖付款时,我们付钱,服务端收钱,服务端收钱成功之后,要向我们发送一条消息告诉我们付款成功了。但是如果由于网络原因,这条消息没有发送成功。我们就有可能再次付款。

这就涉及到网络请求的幂等性(一次和多次请求某一资源应该具有同样的影响)。

实现幂等性,需要客户端和服务器一起改造。

  1. 唯一标识符(Unique Identifier):每次请求都附带一个唯一标识符或者请求 ID,服务端通过这个标识符来判断是否是重复请求。如果服务端已经处理过具有相同标识符的请求,它可以忽略重复的请求。
  2. 乐观锁(Optimistic Locking):在进行修改操作时,记录一个版本号或时间戳,每次请求都携带这个版本号或时间戳。当服务端收到请求时,它会检查当前数据的版本号是否与请求中携带的版本号一致,如果一致则执行操作,否则拒绝请求。
  3. 幂等性接口设计:设计接口时遵循幂等性原则,保证相同的请求在多次执行时不会产生不同的结果。例如,GET 请求通常具有幂等性,因为多次执行相同的 GET 请求不会改变资源的状态。

综上所述,网络请求的幂等性是一种很重要的特性,能够确保在复杂的网络环境中请求的可靠性和数据的一致性。合理设计和处理网络请求,遵循幂等性原则有助于提高系统的可靠性和稳定性。

相关推荐
coding随想3 分钟前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
小小小小宇8 分钟前
一个小小的柯里化函数
前端
灵感__idea12 分钟前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
小小小小宇15 分钟前
前端双Token机制无感刷新
前端
小小小小宇18 分钟前
重提React闭包陷阱
前端
小小小小宇34 分钟前
前端XSS和CSRF以及CSP
前端
UFIT37 分钟前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉44 分钟前
CSS3 的特性
前端·css·css3
星辰引路-Lefan1 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn200011281 小时前
JavaWeb的一些基础技术
前端