從輸入URL到頁面加載完成的過程中都發(fā)生了什么?

2015-10-12 14:16:00 來源:百度Fex 作者:佚名 人氣: 次閱讀 271 條評論

寫這篇文章并不是為了幫大家準備面試,而是想借這道題來介紹計算機和互聯(lián)網(wǎng)的基礎(chǔ)知識,讓讀者了解它們之間是如何關(guān)聯(lián)起來的。...

背景 本文來自于之前我發(fā)的一篇微博:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

不過寫這篇文章并不是為了幫大家準備面試,而是想借這道題來介紹計算機和互聯(lián)網(wǎng)的基礎(chǔ)知識,讓讀者了解它們之間是如何關(guān)聯(lián)起來的。

為了便于理解,我將整個過程分為了六個問題來展開。

第一個問題:從輸入 URL 到瀏覽器接收的過程中發(fā)生了什么事情?

從觸屏到 CPU

首先是「輸入 URL」,大部分人的第一反應(yīng)會是鍵盤,不過為了與時俱進,這里將介紹觸摸屏設(shè)備的交互。

觸摸屏一種傳感器,目前大多是基于電容(Capacitive)來實現(xiàn)的,以前都是直接覆蓋在顯示屏上的,不過最近出現(xiàn)了 3 種嵌入到顯示屏中的技術(shù),第一種是 iPhone 5 的 In-cell,它能減小了 0.5 毫米的厚度,第二種是三星使用的 On-cell 技術(shù),第三種是國內(nèi)廠商喜歡用的 OGS 全貼合技術(shù)。

當(dāng)手指在這個傳感器上觸摸時,有些電子會傳遞到手上,從而導(dǎo)致該區(qū)域的電壓變化,觸摸屏控制器芯片根據(jù)這個變化就能計算出所觸摸的位置,然后通過總線接口將信號傳到 CPU 的引腳上。

以 Nexus 5 為例,它所使用的觸屏控制器是Synaptics S3350B,總線接口為I²C,以下是 Synaptics 觸摸屏和處理器連接的示例:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

左邊是處理器,右邊是觸摸屏控制器,中間的 SDA 和 SCL 連線就是 I²C 總線接口。

CPU 內(nèi)部的處理

移動設(shè)備中的 CPU 并不是一個單獨的芯片,而是和 GPU 等芯片集成在一起,被稱為 SoC(片上系統(tǒng))。

前面提到了觸屏和 CPU 的連接,這個連接和大部分計算機內(nèi)部的連接一樣,都是通過電氣信號來進行通信的,也就是電壓高低的變化,如下面的時序圖:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

在時鐘的控制下,這些電流會經(jīng)過MOSFET晶體管,晶體管中包含 N 型半導(dǎo)體和 P 型半導(dǎo)體,通過電壓就能控制線路開閉,然后這些 MOSFET 構(gòu)成了CMOS,接著再由 CMOS 實現(xiàn)「與」「或」「非」等邏輯電路門,最后由邏輯電路門上就能實現(xiàn)加法、位移等計算,整體如下圖所示(來自《計算機體系結(jié)構(gòu)》):

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

除了計算,在 CPU 中還需要存儲單元來加載和存儲數(shù)據(jù),這個存儲單元一般通過觸發(fā)器(Flip-flop)來實現(xiàn),稱為寄存器。

以上這些概念都比較抽象,推薦閱讀「How to Build an 8-Bit Computer」這篇文章,作者基于晶體管、二極管、電容等原件制作了一個 8 位的計算機,支持簡單匯編指令和結(jié)果輸出,雖然現(xiàn)代 CPU 的實現(xiàn)要比這個復(fù)雜得多,但基本原理還是一樣的。

另外其實我也是剛開始學(xué)習(xí) CPU 芯片的實現(xiàn),所以就不在這誤人子弟了,感興趣的讀者請閱讀本節(jié)后面推薦的書籍。

從 CPU 到操作系統(tǒng)內(nèi)核

前面說到觸屏控制器將電氣信號發(fā)送到 CPU 對應(yīng)的引腳上,接著就會觸發(fā) CPU 的中斷機制,以 Linux 為例,每個外部設(shè)備都有一標識符,稱為中斷請求(IRQ)號,可以通過/proc/interrupts文件來查看系統(tǒng)中所有設(shè)備的中斷請求號,以下是 Nexus 7 (2013) 的部分結(jié)果:

shell@flo:/$cat/proc/interruptsCPU017:0 GICdg_timer294:1973609 msmgpioelan-ktf3k314:679 msmgpioKEY_POWER

因為 Nexus 7 使用了 ELAN 的觸屏控制器,所以結(jié)果中的 elan-ktf3k 就是觸屏的中斷請求信息,其中 294 是中斷號,1973609 是觸發(fā)的次數(shù)(手指單擊時會產(chǎn)生兩次中斷,但滑動時會產(chǎn)生上百次中斷)。

為了簡化這里不考慮優(yōu)先級問題,以 ARMv7 架構(gòu)的處理器為例,當(dāng)中斷發(fā)生時,CPU 會停下當(dāng)前運行的程序,保存當(dāng)前執(zhí)行狀態(tài)(如 PC 值),進入 IRQ 狀態(tài)),然后跳轉(zhuǎn)到對應(yīng)的中斷處理程序執(zhí)行,這個程序一般由第三方內(nèi)核驅(qū)動來實現(xiàn),比如前面提到的 Nexus 7 的驅(qū)動源碼在這里touchscreen/ektf3k.c。

這個驅(qū)動程序?qū)⒆x取 I²C 總線中傳來的位置數(shù)據(jù),然后通過內(nèi)核的input_report_abs等方法記錄觸屏按下坐標等信息,最后由內(nèi)核中的input 子模塊將這些信息都寫進/dev/input/event0這個設(shè)備文件中,比如下面展示了一次觸摸事件所產(chǎn)生的信息:

130|shell@flo:/$getevent-lt/dev/input/event0[414624.658986]EV_ABS ABS_MT_TRACKING_ID 0000835c[414624.659017]EV_ABS ABS_MT_TOUCH_MAJOR 0000000b[414624.659047]EV_ABS ABS_MT_PRESSURE0000001d[414624.659047]EV_ABS ABS_MT_POSITION_X000003f0[414624.659078]EV_ABS ABS_MT_POSITION_Y00000588[414624.659078]EV_SYN SYN_REPORT 00000000[414624.699239]EV_ABS ABS_MT_TRACKING_ID ffffffff[414624.699270]EV_SYN SYN_REPORT 00000000

從操作系統(tǒng) GUI 到瀏覽器

前面提到 Linux 內(nèi)核已經(jīng)完成了對硬件的抽象,其它程序只需要通過監(jiān)聽/dev/input/event0文件的變化就能知道用戶進行了哪些觸摸操作,不過如果每個程序都這么做實在太麻煩了,所以在圖像操作系統(tǒng)中都會包含 GUI 框架來方便應(yīng)用程序開發(fā),比如 Linux 下著名的X。

但 Android 并沒有使用 X,而是自己實現(xiàn)了一套 GUI 框架,其中有個EventHub的服務(wù)會通過epoll方式監(jiān)聽/dev/input/目錄下的文件,然后將這些信息傳遞到 Android 的窗口管理服務(wù)(WindowManagerService)中,它會根據(jù)位置信息來查找相應(yīng)的 app,然后調(diào)用其中的監(jiān)聽函數(shù)(如 onTouch 等)。

就這樣,我們解答了第一個問題,不過由于時間有限,這里省略了很多細節(jié)。

第二個問題:瀏覽器如何向網(wǎng)卡發(fā)送數(shù)據(jù)?

從瀏覽器到瀏覽器內(nèi)核

前面提到操作系統(tǒng) GUI 將輸入事件傳遞到了瀏覽器中,在這過程中,瀏覽器可能會做一些預(yù)處理,比如 Chrome 會根據(jù)歷史統(tǒng)計來預(yù)估所輸入字符對應(yīng)的網(wǎng)站,比如輸入了「ba」,根據(jù)之前的歷史發(fā)現(xiàn) 90% 的概率會訪問「www.baidu.com 」,因此就會在輸入回車前就馬上開始建立 TCP 鏈接甚至渲染了,這里面還有很多其它策略,感興趣的讀者推薦閱讀 High Performance Networking in Chrome。

接著是輸入 URL 后的「回車」,這時瀏覽器會對 URL 進行檢查,首先判斷協(xié)議,如果是 http 就按照 Web 來處理,另外還會對這個 URL 進行安全檢查,然后直接調(diào)用瀏覽器內(nèi)核中的對應(yīng)方法,比如WebView中的 loadUrl 方法。

在瀏覽器內(nèi)核中會先查看緩存,然后設(shè)置 UA 等 HTTP 信息,接著調(diào)用不同平臺下網(wǎng)絡(luò)請求的方法。

需要注意瀏覽器和瀏覽器內(nèi)核是不同的概念,瀏覽器指的是 Chrome、Firefox,而瀏覽器內(nèi)核則是 Blink、Gecko,瀏覽器內(nèi)核只負責(zé)渲染,GUI 及網(wǎng)絡(luò)連接等跨平臺工作則是瀏覽器實現(xiàn)的

HTTP 請求的發(fā)送

因為網(wǎng)絡(luò)的底層實現(xiàn)是和內(nèi)核相關(guān)的,所以這一部分需要針對不同平臺進行處理,從應(yīng)用層角度看主要做兩件事情:通過 DNS 查詢 IP、通過 Socket 發(fā)送數(shù)據(jù),接下來就分別介紹這兩方面的內(nèi)容。

DNS 查詢

應(yīng)用程序可以直接調(diào)用 Libc 提供的getaddrinfo()方法來實現(xiàn) DNS 查詢。

DNS 查詢其實是基于 UDP 來實現(xiàn)的,這里我們通過一個具體例子來了解它的查找過程,以下是使用dig +trace fex.baidu.com命令得到的結(jié)果(省略了一些):

;<<>>DiG9.8.3-P1<<>>+trace fex.baidu.com;;globaloptions:+cmd. 11157 INNSg.root-servers.net.. 11157 INNSi.root-servers.net.. 11157 INNSj.root-servers.net.. 11157 INNSa.root-servers.net.. 11157 INNSl.root-servers.net.;;Received228bytes from8.8.8.8#53(8.8.8.8) in 220 mscom.172800INNSa.gtld-servers.net.com.172800INNSc.gtld-servers.net.com.172800INNSm.gtld-servers.net.com.172800INNSh.gtld-servers.net.com.172800INNSe.gtld-servers.net.;;Received503bytes from192.36.148.17#53(192.36.148.17) in 185 msbaidu.com.172800INNSdns.baidu.com.baidu.com.172800INNSns2.baidu.com.baidu.com.172800INNSns3.baidu.com.baidu.com.172800INNSns4.baidu.com.baidu.com.172800INNSns7.baidu.com.;;Received201bytes from192.48.79.30#53(192.48.79.30) in 1237 msfex.baidu.com.7200INCNAME fexteam.duapp.com.fexteam.duapp.com.300INCNAME duapp.n.shifen.com.n.shifen.com. 86400 INNSns1.n.shifen.com.n.shifen.com. 86400 INNSns4.n.shifen.com.n.shifen.com. 86400 INNSns2.n.shifen.com.n.shifen.com. 86400 INNSns5.n.shifen.com.n.shifen.com. 86400 INNSns3.n.shifen.com.;;Received258bytes from61.135.165.235#53(61.135.165.235) in 2 ms

可以看到這是一個逐步縮小范圍的查找過程,首先由本機所設(shè)置的 DNS 服務(wù)器(8.8.8.8)向 DNS 根節(jié)點查詢負責(zé) .com 區(qū)域的域務(wù)器,然后通過其中一個負責(zé) .com 的服務(wù)器查詢負責(zé) baidu.com 的服務(wù)器,最后由其中一個 baidu.com 的域名服務(wù)器查詢 fex.baidu.com 域名的地址。

可能你在查詢某些域名的時會發(fā)現(xiàn)和上面不一樣,最底將看到有個奇怪的服務(wù)器搶先返回結(jié)果。。。

這里為了方便描述,忽略了很多不同的情況,比如 127.0.0.1 其實走的是loopback,和網(wǎng)卡設(shè)備沒關(guān)系;比如 Chrome 會在瀏覽器啟動的時預(yù)先查詢 10 個你有可能訪問的域名;還有 Hosts 文件、緩存時間 TTL(Time to live)的影響等。

通過 Socket 發(fā)送數(shù)據(jù)

有了 IP 地址,就可以通過 Socket API 來發(fā)送數(shù)據(jù)了,這時可以選擇 TCP 或 UDP 協(xié)議,具體使用方法這里就不介紹了,推薦閱讀 Beej’s Guide to Network Programming。

HTTP 常用的是 TCP 協(xié)議,由于 TCP 協(xié)議的具體細節(jié)到處都能看到,所以本文就不介紹了,這里談一下 TCP 的 Head-of-line blocking 問題:假設(shè)客戶端的發(fā)送了 3 個 TCP 片段(segments),編號分別是 1、2、3,如果編號為 1 的包傳輸時丟了,即便編號 2 和 3 已經(jīng)到達也只能等待,因為 TCP 協(xié)議需要保證順序,這個問題在 HTTP pipelining 下更嚴重,因為 HTTP pipelining 可以讓多個 HTTP 請求通過一個 TCP 發(fā)送,比如發(fā)送兩張圖片,可能第二張圖片的數(shù)據(jù)已經(jīng)全收到了,但還得等第一張圖片的數(shù)據(jù)傳到。

為了解決 TCP 協(xié)議的性能問題,Chrome 團隊去年提出了QUIC協(xié)議,它是基于 UDP 實現(xiàn)的可靠傳輸,比起 TCP,它能減少很多來回(round trip)時間,還有前向糾錯碼(Forward Error Correction)等功能。目前 Google Plus、 Gmail、Google Search、blogspot、Youtube 等幾乎大部分 Google 產(chǎn)品都在使用 QUIC,可以通過chrome://net-internals/#spdy頁面來發(fā)現(xiàn)。

雖然目前除了 Google 還沒人用 QUIC,但我覺得挺有前景的,因為優(yōu)化 TCP 需要升級系統(tǒng)內(nèi)核(比如Fast Open)。

瀏覽器對同一個域名有連接數(shù)限制,大部分是 6,我以前認為將這個連接數(shù)改大后會提升性能,但實際上并不是這樣的,Chrome 團隊有做過實驗,發(fā)現(xiàn)從 6 改成 10 后性能反而下降了,造成這個現(xiàn)象的因素有很多,如建立連接的開銷、擁塞控制等問題,而像 SPDY、HTTP 2.0 協(xié)議盡管只使用一個 TCP 連接來傳輸數(shù)據(jù),但性能反而更好,而且還能實現(xiàn)請求優(yōu)先級。

另外,因為 HTTP 請求是純文本格式的,所以在 TCP 的數(shù)據(jù)段中可以直接分析 HTTP 的文本,如果發(fā)現(xiàn)。。。

Socket 在內(nèi)核中的實現(xiàn)

前面說到瀏覽器的跨平臺庫通過調(diào)用 Socket API 來發(fā)送數(shù)據(jù),那么 Socket API 是如何實現(xiàn)的呢?

以 Linux 為例,它的實現(xiàn)在這里socket.c,目前我還不太了解,推薦讀者看看Linux kernel map,它標注出了關(guān)鍵路徑的函數(shù),方便學(xué)習(xí)從協(xié)議棧到網(wǎng)卡驅(qū)動的實現(xiàn)。

底層網(wǎng)絡(luò)協(xié)議的具體例子

接下來如果繼續(xù)介紹 IP 協(xié)議和 MAC 協(xié)議可能很多讀者會暈,所以本節(jié)將使用Wireshark來通過具體例子講解,以下是我請求百度首頁時抓取到的網(wǎng)絡(luò)數(shù)據(jù):

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

最底下是實際的二進制數(shù)據(jù),中間是解析出來的各個字段值,可以看到其中最底部為 HTTP 協(xié)議(Hypertext Transfer Protocol),在 HTTP 之前有 54 字節(jié)(0×36),這就是底層網(wǎng)絡(luò)協(xié)議所帶來的開銷,我們接下來對這些協(xié)議進行分析。

在 HTTP 之上是 TCP 協(xié)議(Transmission Control Protocol),它的具體內(nèi)容如下圖所示:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

通過底部的二進制數(shù)據(jù),可以看到 TCP 協(xié)議是加在 HTTP 文本前面的,它有 20 個字節(jié),其中定義了本地端口(Source port)和目標端口(Destination port)、順序序號(Sequence Number)、窗口長度等信息,以下是 TCP 協(xié)議各個部分數(shù)據(jù)的完整介紹:

0 1 2 3

01234567890123456789012345678901+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Source Port| Destination Port|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Sequence Number|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Acknowledgment Number|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Data| |U|A|E|R|S|F| ||Offset|Reserved|R|C|O|S|Y|I|Window || | |G|K|L|T|N|N| |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Checksum| Urgent Pointer|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Options|Padding|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| data|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

具體各個字段的作用這里就不介紹了,感興趣的讀者可以閱讀RFC 793,并結(jié)合抓包分析來理解。

需要注意的是,在 TCP 協(xié)議中并沒有 IP 地址信息,因為這是在上一層的 IP 協(xié)議中定義的,如下圖所示:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

IP 協(xié)議同樣是在 TCP 前面的,它也有 20 字節(jié),在這里指明了版本號(Version)為 4,源(Source) IP 為192.168.1.106,目標(Destination) IP 為119.75.217.56,因此 IP 協(xié)議最重要的作用就是確定 IP 地址。

因為 IP 協(xié)議中可以查看到目標 IP 地址,所以如果發(fā)現(xiàn)某些特定的 IP 地址,某些路由器就會。。。

但是,光靠 IP 地址是無法進行通信的,因為 IP 地址并不和某臺設(shè)備綁定,比如你的筆記本的 IP 在家中是192.168.1.1,但到公司就變成172.22.22.22了,所以在底層通信時需要使用一個固定的地址,這就是 MAC(media Access control) 地址,每個網(wǎng)卡出廠時的 MAC 地址都是固定且唯一的。

因此再往上就是 MAC 協(xié)議,它有 14 字節(jié),如下所示:

頁面加載 網(wǎng)站響應(yīng)流程 網(wǎng)站URL

當(dāng)一臺電腦加入網(wǎng)絡(luò)時,需要通過ARP協(xié)議告訴其它網(wǎng)絡(luò)設(shè)備它的 IP 及對應(yīng)的 MAC 地址是什么,這樣其它設(shè)備就能通過 IP 地址來查找對應(yīng)的設(shè)備了。

最頂上的 Frame 是代表 Wireshark 的抓包序號,并不是網(wǎng)絡(luò)協(xié)議。

就這樣,我們解答了第二個問題,不過其實這里面還有很多很多細節(jié)沒介紹。

第三個問題:數(shù)據(jù)如何從本機網(wǎng)卡發(fā)送到服務(wù)器?

從內(nèi)核到網(wǎng)絡(luò)適配器(Network Interface Card)

前面說到調(diào)用 Socket API 后內(nèi)核會對數(shù)據(jù)進行底層協(xié)議棧的封裝,接下來啟動DMA控制器,它將從內(nèi)存中讀取數(shù)據(jù)寫入網(wǎng)卡。

以 Nexus 5 為例,它使用的是博通BCM4339芯片通信,接口采用了 SD 卡一樣的SDIO,但這個芯片的細節(jié)并沒有公開資料,所以這里就不討論了。

連接 Wi-Fi 路由

Wi-Fi 網(wǎng)卡需要通過 Wi-Fi 路由來與外部通信,原理是基于無線電,通過電流變化來產(chǎn)生無線電,這個過程也叫「調(diào)制」,而反過來無線電可以引起電磁場變化,從而產(chǎn)生電流變化,利用這個原理就能將無線電中的信息解讀出來就叫「解調(diào)」,其中單位時間內(nèi)變化的次數(shù)就稱為頻率,目前在 Wi-Fi 中所采用的頻率分為 2.4 GHz 和 5 GHz 兩種。

在同一個 Wi-Fi 路由下,因為采用的頻率相同,同時使用時會發(fā)生沖突,為了解決這個問題,Wi-Fi 采用了被稱為CSMA/CA的方法,簡單來說就是在傳輸前先確認信道是否已被使用,沒有才發(fā)送數(shù)據(jù)。

而同樣基于無線電原理的 2G/3G/LTE 也會遇到類似的問題,但它并沒有采用 Wi-Fi 那樣的獨占方案,而是通過頻分(FDMA)、時分(TDMA)和碼分(CDMA)來進行復(fù)用,具體細節(jié)這里就不展開了。

小米路由為例,它使用的芯片是BCM 4709,這個芯片由 ARM Cortex-A9 處理器及流量(Flow)硬件加速組成,使用硬件芯片可以避免經(jīng)過操作系統(tǒng)中斷、上下文切換等操作,從而提升了性能。

路由器中的操作系統(tǒng)可以基于OpenWrt或DD-WRT來開發(fā)的,具體細節(jié)我不太了解,所以就不展開了。

因為內(nèi)網(wǎng)設(shè)備的 IP 都是類似192.168.1.x這樣的內(nèi)網(wǎng)地址,外網(wǎng)無法直接向這個地址發(fā)送數(shù)據(jù),所以網(wǎng)絡(luò)數(shù)據(jù)在經(jīng)過路由時,路由會修改相關(guān)地址和端口,這個操作稱為NAT映射。

最后家庭路由一般會通過雙絞線連接到運營商網(wǎng)絡(luò)的。

運營商網(wǎng)絡(luò)內(nèi)的路由

數(shù)據(jù)過雙絞線發(fā)送到運營商網(wǎng)絡(luò)后,還會經(jīng)過很多個中間路由轉(zhuǎn)發(fā),讀者可以通過 traceroute 命令或者在線可視化工具來查看這些路由的 ip 和位置。

當(dāng)數(shù)據(jù)傳遞到這些路由器后,路由器會取出包中目的地址的前綴,通過內(nèi)部的轉(zhuǎn)發(fā)表查找對應(yīng)的輸出鏈路,而這個轉(zhuǎn)發(fā)表是如何得到的呢?這就是路由器中最重要的選路算法了,可選的有很多,我對這方面并不太了解,看起來維基百科上的詞條列得很全。

主干網(wǎng)間的傳輸

對于長線的數(shù)據(jù)傳輸,通常使用光纖作為介質(zhì),光纖是基于光的全反射來實現(xiàn)的,使用光纖需要專門的發(fā)射器通過電致發(fā)光(比如 LED)將電信號轉(zhuǎn)成光,比起前面介紹的無線電和雙絞線,光纖信號的抗干擾性要強得多,而且能耗也小很多。

既然是基于光來傳輸數(shù)據(jù),數(shù)據(jù)傳輸速度也就取決于光的速度,在真空中的光速接近于 30 萬千米/秒,由于光纖包層(cladding)中的折射率(refractive index)為 1.52,所以實際光速是 20 萬千米/秒左右,從首都機場飛往廣州白云機場的距離是 1967 千米,按照這個距離來算需要花費 10 毫秒才能抵達。這意味著如果你在北京,服務(wù)器在廣州,等你發(fā)出數(shù)據(jù)到服務(wù)器返回數(shù)據(jù)至少得等 20 毫秒,實際情況預(yù)計是 2- 3 倍,因為這其中還有各個節(jié)點路由處理的耗時,比如我測試了一個廣州的 IP 發(fā)現(xiàn)平均延遲為 60 毫秒。

這個延遲是現(xiàn)有科技無法解決的(除非找到超過光速的方法),只能通過 CDN 來讓傳輸距離變短,或盡量減少串行的來回請求(比如 TCP 建立連接所需的 3 次握手)。

您可能感興趣的文章

相關(guān)文章