在網(wǎng)路應(yīng)用流行的今天,我們已經(jīng)很難再找到哪些應(yīng)用是不需要網(wǎng)路的了,那么網(wǎng)路質(zhì)量的好壞極大關(guān)系的影響著一個(gè)app的體驗(yàn)。
弱網(wǎng)環(huán)境
當(dāng)提到這個(gè)詞的時(shí)候我們可能會(huì)疑惑?什么叫弱網(wǎng)環(huán)境?
現(xiàn)在大部分人的手機(jī)都是4G手機(jī),當(dāng)我們使用手機(jī)流量時(shí)在信號(hào)不好的地方可能會(huì)降級(jí)到3G,2G,那么這些意味著手機(jī)信號(hào)不好的時(shí)候手機(jī)會(huì)去調(diào)整到一個(gè)高延遲低帶寬的網(wǎng)絡(luò)環(huán)境。
| 網(wǎng)絡(luò)環(huán)境 | 2.75G | 3G | 4G | 5G |
|---|---|---|---|---|
| 帶寬(上行/下行) | 484kb/384kb | 2m/7m | 56-128m | >50m/>100m |
| 延遲 | 600-700ms | 150-400ms | 40-50ms | 10ms |
可以看到不同制式的網(wǎng)絡(luò)標(biāo)準(zhǔn)能夠提供的網(wǎng)絡(luò)環(huán)境是不一樣的。
弱網(wǎng)環(huán)境下會(huì)有很多問題
- 丟包率高
- 誤碼率高
- 不穩(wěn)定的延遲
- 不穩(wěn)定的帶寬
我們?cè)u(píng)測(cè)一個(gè)網(wǎng)絡(luò)是否好通常通過以下幾個(gè)參數(shù)去判定
- 吞吐量:網(wǎng)絡(luò)接口接受和傳輸?shù)拿棵胱止?jié)數(shù)。
- 延遲:系統(tǒng)調(diào)用發(fā)送/接受延遲,連接延遲,首包延遲,網(wǎng)絡(luò)往返時(shí)間等。
- 連接數(shù):每秒的連接數(shù)
- 錯(cuò)誤:丟包計(jì)數(shù),超時(shí)等。

網(wǎng)絡(luò)優(yōu)化
什么事網(wǎng)絡(luò)優(yōu)化?網(wǎng)絡(luò)優(yōu)化在優(yōu)化哪些內(nèi)容?
- 速度。在網(wǎng)絡(luò)正?;蛘吡己玫臅r(shí)候,怎樣更好地利用帶寬,進(jìn)一步提升網(wǎng)絡(luò)請(qǐng)求速度。
- 弱網(wǎng)絡(luò)。移動(dòng)端網(wǎng)絡(luò)復(fù)雜多變,在出現(xiàn)網(wǎng)絡(luò)連接不穩(wěn)定的時(shí)候,怎樣最大程度保證網(wǎng)絡(luò)
的連通性。 - 安全。網(wǎng)絡(luò)安全不容忽視,怎樣有效防止被第三方劫持、竊聽甚至篡改。

- DNS 解析。通過 DNS 服務(wù)器,拿到對(duì)應(yīng)域名的 IP 地址。在這個(gè)步驟,我們比較關(guān)注 DNS 解析耗時(shí)情況、運(yùn)營(yíng)商 LocalDNS 的劫持、DNS 調(diào)度這些問題。
- 創(chuàng)建連接。跟服務(wù)器建立連接,這里包括 TCP 三次握手、TLS 密鑰協(xié)商等工作。多個(gè) IP/ 端口該如何選擇、是否要使用 HTTPS、能否可以減少甚至省下創(chuàng)建連接的時(shí)間,這 些問題都是我們優(yōu)化的關(guān)鍵。
- 發(fā)送 / 接收數(shù)據(jù)。在成功建立連接之后,就可以愉快地跟服務(wù)器交互,進(jìn)行組裝數(shù)據(jù)、 發(fā)送數(shù)據(jù)、接收數(shù)據(jù)、解析數(shù)據(jù)。我們關(guān)注的是,如何根據(jù)網(wǎng)絡(luò)狀況將帶寬利用好,怎 么樣快速地偵測(cè)到網(wǎng)絡(luò)延時(shí),在弱網(wǎng)絡(luò)下如何調(diào)整包大小等問題。
- 關(guān)閉連接。連接的關(guān)閉看起來非常簡(jiǎn)單,其實(shí)這里的水也很深。這里主要關(guān)注主動(dòng)關(guān)閉 和被動(dòng)關(guān)閉兩種情況,一般我們都希望客戶端可以主動(dòng)關(guān)閉連接。
DNS解析
DNS 的解析是我們網(wǎng)絡(luò)請(qǐng)求的第一項(xiàng)工作,默認(rèn)我們使用運(yùn)營(yíng)商的 LocalDNS 服務(wù)。這 塊耗時(shí)在 3G 網(wǎng)絡(luò)下可能是 200~300ms,4G 網(wǎng)絡(luò)也需要 100ms。
微信有自己部署的 NEWDNS,阿里云和騰訊云也有提供自己的 HTTPDNS 服務(wù)。對(duì)于大 網(wǎng)絡(luò)平臺(tái)來說,我們會(huì)有統(tǒng)一的 HTTPDNS 服務(wù),并將它和運(yùn)維系統(tǒng)打通。在傳統(tǒng)的 DNS 基礎(chǔ)上,還會(huì)增加精準(zhǔn)的流量調(diào)度、網(wǎng)絡(luò)撥測(cè) / 灰度、網(wǎng)絡(luò)容災(zāi)等功能。

連接復(fù)用
tcp連接需要進(jìn)行三次握手,tls連接需要進(jìn)行秘鑰協(xié)商然后建立連接,創(chuàng)建連接的代價(jià)是非常大的,可以通過復(fù)用連接來避免每次請(qǐng)求都進(jìn)行重新建立連接。
在okhttp中當(dāng)一次請(qǐng)求完成后,并不會(huì)立刻把連接釋放,而是放到連接池中。這時(shí)如果 有另一個(gè)請(qǐng)求的域名和端口是一樣的,就直接拿出連接池中的連接進(jìn)行發(fā)送和接收數(shù)據(jù), 少了建立連接的耗時(shí)。
這里我們利用 HTTP 協(xié)議里的 keep-alive,而 HTTP/2.0 的多路復(fù)用則可以進(jìn)一步的提升 連接復(fù)用率。它復(fù)用的這條連接支持同時(shí)處理多條請(qǐng)求,所有請(qǐng)求都可以并發(fā)在這條連接 上進(jìn)行。
壓縮與加密
壓縮
講完連接,我們?cè)賮砜纯窗l(fā)送和接收的優(yōu)化。我第一時(shí)間想到的還是減少傳輸?shù)臄?shù)據(jù)量, 也就是我們常說的數(shù)據(jù)壓縮。首先對(duì)于 HTTP 請(qǐng)求來說,數(shù)據(jù)主要包括三個(gè)部分:請(qǐng)求 URL 請(qǐng)求 header 請(qǐng)求 body。
- 對(duì)于 header 來說,如果使用 HTTP/2.0 連接本身的頭部壓縮技術(shù),因此需要壓縮的主要 是請(qǐng)求 URL 和請(qǐng)求 body。
- 對(duì)于請(qǐng)求 URL 來說,一般會(huì)帶很多的公共參數(shù),這些參數(shù)大部分都是不變的。這樣不變的 參數(shù)客戶端只需要上傳一次即可,其他請(qǐng)求我們可以在接入層中進(jìn)行參數(shù)擴(kuò)展。
- 對(duì)于請(qǐng)求 body 來說,一方面是數(shù)據(jù)通信協(xié)議的選擇,在網(wǎng)絡(luò)傳輸中目前最流行的兩種數(shù) 據(jù)序列化方式是 JSON 和 Protocol Buffers。正如我之前所說的一樣,Protocol Buffers 使用起來更加復(fù)雜一些,但在數(shù)據(jù)壓縮率、序列化與反序列化速度上面都有很大的優(yōu)勢(shì)。
另外一方面是壓縮算法的選擇,通用的壓縮算法主要是如 gzip,Google 的Brotli或者 Facebook 的Z-standard都是壓縮率更高的算法。其中如果 Z-standard 通過業(yè)務(wù)數(shù)據(jù)樣 本訓(xùn)練出適合的字典,是目前壓縮率表現(xiàn)最好的算法。但是各個(gè)業(yè)務(wù)維護(hù)字典的成本比較 大,這個(gè)時(shí)候我們的大網(wǎng)絡(luò)平臺(tái)的統(tǒng)一接入層又可以大顯神威了。

針對(duì)圖片可以通過得知網(wǎng)絡(luò)環(huán)境提供不同分辨率和質(zhì)量的圖片來節(jié)省網(wǎng)絡(luò)帶寬