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

概述

一次网络请求的操作,是从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 请求不会改变资源的状态。

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

相关推荐
everyStudy18 分钟前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白18 分钟前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、19 分钟前
Web Worker 简单使用
前端
web_learning_32122 分钟前
信息收集常用指令
前端·搜索引擎
tabzzz29 分钟前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百42 分钟前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao1 小时前
自动化测试常用函数
前端·css·html5
码爸1 小时前
flink doris批量sink
java·前端·flink
深情废杨杨1 小时前
前端vue-父传子
前端·javascript·vue.js
J不A秃V头A2 小时前
Vue3:编写一个插件(进阶)
前端·vue.js