對(duì)于一個(gè)用戶來說,判斷一個(gè)網(wǎng)站好壞的首要指標(biāo)就是網(wǎng)站的打開速度。有研究表明:用戶打開網(wǎng)站最滿意的時(shí)間是3秒以下,網(wǎng)站打開時(shí)間超過10秒,就會(huì)有98%的用戶選擇直接關(guān)閉網(wǎng)站。如此嚴(yán)重的用戶流失對(duì)于站長(zhǎng)和企業(yè)來說,都是非常嚴(yán)重的問題:無論你的網(wǎng)站布局有多么合理,素材有多么精美,內(nèi)容有多么無敵,都再無用武之地。這時(shí)候,我們?cè)撛趺崔k?
在開始分析解決問題前,先得對(duì)整個(gè)網(wǎng)站系統(tǒng)有個(gè)清晰的理解。網(wǎng)站是單機(jī)部署,還是多機(jī)部署?有沒有用到負(fù)載均衡?當(dāng)前網(wǎng)站的QPS多高,各機(jī)器負(fù)載情況如何?最好能用可視化圖形畫出清晰架構(gòu)。
除此之外,我們也需要知道瀏覽器請(qǐng)求背后的原理:當(dāng)用戶在瀏覽器輸入完一個(gè)網(wǎng)址,這背后經(jīng)歷了一系列復(fù)雜的流程才能最終將頁面呈現(xiàn)出來:比如DNS解析、TCP建連、TLS握手、瀏覽器解析和渲染(詳細(xì)流程可以參考:https://github.com/alex/what-happens-when)。這其中每一個(gè)環(huán)節(jié)出了問題,都可能導(dǎo)致最終網(wǎng)站打開速率降低。那么,我們應(yīng)該怎么快速找到問題點(diǎn)?
01 分析定位問題
首先,要定位網(wǎng)站打開慢的原因,通常有以下幾種方法:
·客戶端信息收集
我們一般需要用戶配合,提供一些基礎(chǔ)信息:
·問題是否必現(xiàn) /是首次打開慢,還是每次打開都很慢?
如果只是首次打開慢,說明是本地沒緩存。如果每次打開都慢,說明服務(wù)端緩存配置可能不正確,或者站點(diǎn)包含了太多動(dòng)態(tài)請(qǐng)求。
·是否共性問題 /除了本站點(diǎn)打開慢,打開大流量網(wǎng)站(比如www.qq.com)也慢嗎?
如果大流量站點(diǎn)打開也慢,極可能說明本地網(wǎng)絡(luò)或者DNS存在問題。否則,可能是本站點(diǎn)的原因。
·是否網(wǎng)絡(luò)差異 /切換不同的WiFi,或者切換熱點(diǎn)重試,是否有改善?
如果WiFi/熱點(diǎn)訪問體驗(yàn)不同,也可能說明是網(wǎng)絡(luò)鏈路問題。比如服務(wù)器在電信網(wǎng)絡(luò),而客戶端在移動(dòng),跨網(wǎng)互聯(lián)會(huì)存在天然的延時(shí)。
·其他用戶是否有類似問題
如果只是個(gè)別客戶端出問題,基本能確定是客戶端自身原因。
我們可以保持和客戶交流,通過提問的方式驗(yàn)證自己的猜想,不斷地把不可能的因素排除掉,確定排查方向。
·抓包
除了找用戶收集信息之外,我們還可以引導(dǎo)用戶借助瀏覽器抓包診斷。比如Chrome就有開發(fā)者工具,其中network面板可以分析資源加載時(shí)序,查看每個(gè)資源的加載時(shí)間,定位到加載慢的資源,詳細(xì)操作:https://developer.chrome.com/docs/devtools/network/。
·診斷工具
除了主動(dòng)詢問客戶外,也可以利用自動(dòng)化診斷工具來快速獲取客戶端的ip、localDNS、瀏覽器版本等基礎(chǔ)信息,http://debug.ping.dnsv1.com/ping.x。
·第三方探測(cè)
有時(shí)候,為了判斷問題是個(gè)例行為還是共性行為,我們可以借助第三方探測(cè)工具來排查。比如一次性探測(cè)工具:https://www.17ce.com/,周期性探測(cè)系統(tǒng)可以用博睿、基調(diào)等公司提供的服務(wù)。
·主動(dòng)監(jiān)控
為了更快、更主動(dòng)的發(fā)現(xiàn)客戶端的異常,一般情況下我們也需要在業(yè)務(wù)代碼中做一些埋點(diǎn)上報(bào)邏輯,將頁面加載的延時(shí)等基礎(chǔ)信息上報(bào)服務(wù)端,用于分析訪問情況,對(duì)頁面優(yōu)化有極大的參考作用。
不僅僅是頁面內(nèi)要做埋點(diǎn)上報(bào)邏輯,對(duì)于服務(wù)端,我們也需要做好監(jiān)控,將服務(wù)器基礎(chǔ)信息(CPU/內(nèi)存/磁盤/tcp連接/文件描述符)以及業(yè)務(wù)維度指標(biāo)(請(qǐng)求QPS、請(qǐng)求時(shí)延、線程池?cái)?shù)量)上報(bào)至監(jiān)控系統(tǒng)。當(dāng)系統(tǒng)具備了全面的監(jiān)控,碰到問題時(shí)我們才不會(huì)盲目,可以順著監(jiān)控曲線快速驗(yàn)證猜想,排除干擾,定位到根因。
以上粗略列舉了分析定位問題的一些手段,實(shí)際操作過程中我們往往需要綜合多種方式來找到問題。
02 問題解決方案
定位到根因后,我們便可以針對(duì)性提出解決方案。
·客戶端原因
如果是客戶端網(wǎng)絡(luò)/DNS解析異常,需要聯(lián)系本地網(wǎng)絡(luò)服務(wù)提供商解決。
·服務(wù)端原因
1.服務(wù)器CPU高負(fù)載
一般情況下,這意味著請(qǐng)求量超出了服務(wù)器承受能力,資源已耗盡,需要擴(kuò)容新服務(wù)器。有以下方式:
1)LB服務(wù)端負(fù)載均衡
可以引入負(fù)載均衡服務(wù),比如騰訊云CLB,能將來自客戶端的請(qǐng)求以特定的均衡算法派發(fā)到后端服務(wù)器上,降低單臺(tái)服務(wù)器壓力。并且還可以探測(cè)后臺(tái)服務(wù)器存活性,自動(dòng)剔除掉不健康的節(jié)點(diǎn)。
2)DNS全局負(fù)載均衡
如果請(qǐng)求量超出了單臺(tái)LB承受能力,這時(shí)LB也可能會(huì)掛掉,因此可以引入多個(gè)負(fù)載均衡服務(wù),為了讓客戶端能發(fā)現(xiàn)多臺(tái)負(fù)載均衡,我們可以修改DNS解析,添加多個(gè)LB ip作為A記錄。
3)接入CDN
如果網(wǎng)站業(yè)務(wù)正處于一個(gè)上升期,流量預(yù)計(jì)會(huì)有不小的增長(zhǎng),為了跟上業(yè)務(wù)發(fā)展的節(jié)奏,我們會(huì)需要頻繁擴(kuò)容,這是一個(gè)繁瑣的過程,費(fèi)力不說,購買新LB和服務(wù)器都需要不小的服務(wù)器、網(wǎng)絡(luò)帶寬成本。這時(shí),我們可以考慮將網(wǎng)站接入CDN。對(duì)于靜態(tài)資源類網(wǎng)站,CDN可以將絕大部分資源緩存在邊緣節(jié)點(diǎn)上,提升最后一公里用戶的訪問效率,為服務(wù)器抵擋住接近100%的流量,CDN加速產(chǎn)生的流量相比普通服務(wù)器產(chǎn)生的流量更廉價(jià),因此可以大大減少網(wǎng)站服務(wù)器成本。騰訊云CDN就提供了這樣的能力。
2.網(wǎng)絡(luò)帶寬打滿
此時(shí)可以選擇帶寬擴(kuò)容,或者接入CDN,相對(duì)來說,CDN加速帶寬相比服務(wù)器帶寬更廉價(jià),是更好的選擇。
3.服務(wù)器首包響應(yīng)慢
這意味著服務(wù)器負(fù)責(zé)正常,但業(yè)務(wù)側(cè)處理能力跟不上,可能有以下幾類原因:
1)WEB服務(wù)器性能太差。比如Apache服務(wù)器,由于每個(gè)連接都需要?jiǎng)?chuàng)建新線程處理,在高并發(fā)量請(qǐng)求場(chǎng)景下線程創(chuàng)建銷毀以及切換開銷都不小,因此可以換用性能更好的服務(wù)器軟件nginx。
2)磁盤IO高負(fù)載??梢钥紤]服務(wù)器內(nèi)存做緩存,內(nèi)存讀寫效率相比磁盤有很大提升,可以顯著提升性能。如果覺得改造成本比較高,又不差錢的話,可以選用SSD硬盤,也能有不錯(cuò)的提升效果。
4.網(wǎng)絡(luò)傳輸慢
客戶端和服務(wù)端處在不同網(wǎng)絡(luò),或者客戶端和服務(wù)端處于不同區(qū)域,都可能造成網(wǎng)絡(luò)傳輸慢。此時(shí),我們可以從協(xié)議棧上全棧做優(yōu)化。
1)物理上,就近部署服務(wù)。將服務(wù)器靠近目標(biāo)用戶,并且同網(wǎng)絡(luò)部署,降低路由跳數(shù),但如果目標(biāo)用戶廣泛分布,此法解決不了問題。
2)傳輸層上,我們可以對(duì)tcp參數(shù)做調(diào)優(yōu),比如linux有net.ipv4.tcp_max_syn_backlog/net.ipv4.tcp_rmem/net.core.somaxconn等參數(shù)可以配置。也可以換用更好的擁塞控制算法,比如bbr。
3)應(yīng)用層協(xié)議上,可以啟用傳輸效率更好的HTTP2、QUIC協(xié)議。
4)應(yīng)用開發(fā)上,有非常多優(yōu)化方式。比如將多個(gè)css/js文件打包合并,減少分散加載引入的慢啟動(dòng)時(shí)延??梢詫⑽谋绢愇募嚎s傳輸??梢钥梢栽跒g覽器、內(nèi)存、磁盤、中間件上做各級(jí)緩存,可以將外鏈本地存放,圖片內(nèi)容base64編碼,為站點(diǎn)申請(qǐng)多個(gè)域名,解決瀏覽器同個(gè)域名最大6個(gè)tcp連接的限制。
5)使用CDN。騰訊云CDN在全球廣泛部署有非常多緩存節(jié)點(diǎn),資源一旦在節(jié)點(diǎn)上緩存下來,后續(xù)客戶端都能直接從最近的節(jié)點(diǎn)拿到內(nèi)容,因此顯著降低地理位置差異引入的延時(shí)。此外,騰訊云CDN支持智能壓縮傳輸、支持HTTP2/QUIC協(xié)議,能幫助站點(diǎn)在不改造的情況下更進(jìn)一步提升傳輸效率。
?綜合來看,將網(wǎng)站接入CDN是最省事、成本最低、并且加速效果最好的一種方式。
最后我們以一個(gè)靜態(tài)網(wǎng)站樣例來說明應(yīng)用以上一些優(yōu)化手段后的效果。
03 實(shí)戰(zhàn)演練
這是一個(gè)AdminLTE3的示例頁面,首頁上加載資源很多,我們按加載時(shí)長(zhǎng)從大往小排序,可以看到,在沒優(yōu)化前,頁面總共加載耗時(shí)8.48s。其中adminlte.min.css文件加載就花了4.68s,耗時(shí)最多。
查看server回包,可以看到缺失Transfer-Encoding、Content-Encoding這樣的頭部,說明未啟用壓縮。
1.nginx開啟壓縮傳輸
我們配置服務(wù)器nginx,啟用傳輸壓縮,再看看效果。
可以看到adminlte.min.css加載時(shí)間降低為724ms,只有之前的15%。網(wǎng)站總體加載時(shí)間6.02s,比之前8.48s降低了一些。
server返回頭部中確實(shí)攜帶了Content-Encoding、Transfer-Encoding。
2.接入CDN
我們以騰訊云CDN接入來說明,只需要簡(jiǎn)單幾步操作即可快速啟用CDN加速。
1)接入域名
在騰訊云CDN控制臺(tái)上,最簡(jiǎn)單的操作,只需要將加速域名,源站ip填寫進(jìn)來,點(diǎn)擊確認(rèn)提交即可創(chuàng)建域名配置。
2)調(diào)整解析
域名配置創(chuàng)建好后,會(huì)分配一個(gè)CNAME,該CNAME即是接入CDN的關(guān)鍵,可以將客戶端DNS請(qǐng)求調(diào)度到最優(yōu)CDN節(jié)點(diǎn)。我們只需要將原始域名添加一條CNAME類型記錄指向該CNAME即可。
最終DNS解析關(guān)系應(yīng)該如下:
3)查看域名配置
騰訊云CDN默認(rèn)為靜態(tài)站點(diǎn)開啟了智能壓縮特性,還有其他功能,讀者可以自行挖掘。
4)驗(yàn)證加速效果
再一次訪問站點(diǎn),由于請(qǐng)求由就近CDN節(jié)點(diǎn)提供服務(wù),這里加載延時(shí)進(jìn)一步降低,并且總體加載時(shí)間也只有3.24s,比原始站點(diǎn)開啟壓縮之后的6.02s提速效果大大增加。
5)啟用QUIC加速
除了以上優(yōu)化,我們還可以在騰訊云CDN控制臺(tái)上為域名啟用QUIC特性,提高傳輸效率。
6)再一次驗(yàn)證
可以看到,css加載延時(shí)進(jìn)一步降低,總體加載時(shí)間只有2.15s。
·網(wǎng)站頁面加載速度優(yōu)化的方法有很多,有實(shí)力、愛折騰的開發(fā)者可以通過調(diào)整軟件設(shè)計(jì)、架構(gòu)以及服務(wù)器配置達(dá)到加速效果。除此之外,最簡(jiǎn)單、便捷的方法就是將網(wǎng)站接入CDN,快速啟用壓縮、QUIC特性,達(dá)到既節(jié)省成本,又靈活,還能大幅提速的目的。
參考文獻(xiàn)
[1]web性能權(quán)威指南
[2]https://www.nngroup.com/articles/
response-times-3-important-limits/
[3]https://github.com/alex/what-happens-when