天天看點

性能架構師看IT之家的性能問題及解法

2016.10.27網上出來一篇熱文《it之家公告:完成阿裡雲至百度雲站點遷移工作》,作為一名朝陽吃瓜群衆,兼前微軟msn.com(全球流量排名top 3門戶)、msdn的性能架構師,不分析公關戰,隻從技術角度分析一下這件事情之我見,主要有以下幾個問題,與用哪家雲無關。

<b>blocking js</b>

出于本能,我很快就以最“庸俗”的測試方法,用httpwatch(網頁性能測試工具)看看it之家(ithome.com)的首頁構成結構waterfall,進行了plt1(首次通路,不帶cache和cookie)和plt2(重複通路,帶cache和cookie)測試。

首頁沒啥大問題,但看文章就明顯示卡了(測的時候是2016.10.28,根據ithome自己的說法應該已經在百度雲上了),基本45秒~1分半白屏(網頁不能操作,唯一可能就是js blocking)。

例如打開《放個大招:如何高效完全地毀滅整個宇宙?》http://www.ithome.com/html/discovery/267809.htm,看一下httpwatch的waterfall chart:

性能架構師看IT之家的性能問題及解法

足足1分45秒在等待loading一個廣告javascript:http://pagead2.googlesyndication.com/pagead/show_ads.js,重複了ie 9 和chrome都是同樣問題,隻是等待時間從45秒到1分多鐘不等。

這個js是其上方的http://pos.baidu.com/yckm?di這個百度廣告js請求的,你真的确定要請求一個google的域名麼?如果是跨國的,那就是被偉大的great firewall給牆了,唯一的結果就是等待這個請求逾時傳回,timeout時間可能就是那麼長……

如果這個google域名在牆内,也要看鍊路用哪家營運商。是以這就是為啥在it之家的公告之下有不少群衆反映遷移後還是慢。

load這個js的百度請求源代碼是這麼寫的,明顯是synchronizationjavascript(同步請求):

性能架構師看IT之家的性能問題及解法

就是最普通的&lt;script src = “…”&gt;的寫法,大學生計算機第一課就教了。但踏上工作崗位進入像百度這樣的大企業不該繼續寫這麼幼稚的javascript loading方式啊,這個request不需要用synchronization javascript保證加載順序的……

<b>給大家科普一下:</b>

1. 一個synchronization javascript加載(&lt;script src = “…”&gt;),其裡面請求的js加載多少時間,就會block整個浏覽器多少時間,block的意思是網頁根本不動,滾動條都沒法動。

2. js如果屬于跨國被牆的域名,就會出現經典的“白屏”效果。可以很簡單地嘗試一個實驗:寫一個hello world網頁,上面放一個來自于google或facebook的javascript,例如&lt;script src = “http://www.google.com/xxx.js”&gt;,然後自己打開看看是否要很久都是白屏。

國外有些網站不知道這一經典陷阱,在國内打開時,發現各種加載慢或基本打不開,很多就是這個原因。

是以,it之家和阿裡雲,你們貌似都被百度躺槍了……

解法很簡單,就三行code,用bing搜尋一下non-blocking javascript,不用我寫了,一看就明白。

<b>cache(緩存)&amp; cdn</b>

it之家有很多圖檔,但在重複加載時候,還是需要浪費請求去詢問一下server要不要加載,傳回304(已經cache緩存了)。細看一下每個圖檔的http header,基本都是設了超短的近乎無效的expiration header

性能架構師看IT之家的性能問題及解法
性能架構師看IT之家的性能問題及解法

來來回回幾十個無意義的請求其實是會block住後面重要資源的加載,會讓網頁看起來一卡一卡有些慢。解法是設一個長一點的expiration header就可以了。

再談一下cdn,很多人以為cdn cache一下圖檔css js等靜态資源就差不多了,其實不知cdn可以cache幾乎任何東西,即使是一個動态資源請求,對于cdn來說也就是一個檔案,照樣可以cache。

以筆者之前的經曆,msn.com這個全球top 3的門戶網站,每日pv都是好幾億的,相比it之家流量要大幾百倍,而且是全球通路都保持plt在1秒左右,在it界幾乎屬于mission impossible(申明一下真不是做廣告)。我們對其中一個流量超大的闆塊做performance tuning,将很多原先認為不能cache的動态資源|請求,都設了cache header放在cdn上面,就是timeout時間設短一點,例如1-15分鐘(根據業務需求情況而定),甚至包括base頁面即主請求main request(不可思議吧)。

結果是幾乎沒有什麼request被傳輸到web server,基本全部被cdn以“靜态資源cache”擋在門外,對于cdn簡直是九牛一毛,web server的cpu輕松地我們都以為沒開機呢,都在一位數左右,最終将76台伺服器縮減到僅剩4台,而且4台根本cpu都在個位數,用4台的原因僅僅是用來做容災……

這是為什麼呢?很簡單,靜态資源(static request)如圖檔、css、js對于web server的cpu消耗非常少,但是動态請求(dynamic request)就要走遍web server的全鍊路,對于資源消耗非常高,通常展現在cpu。然後不單是iis連接配接池,就連很多要查詢資料庫的request都繼續被送往sql server資料庫(即使得到的response data是跟之前請求一模一樣的),然後,然後sql server就跟着一起cpu high了。

是以其實很多情況下,像it之家這種門戶網站,單條内容更新頻率其實并不高,可以說90%以上的内容都是可以被cache的,評論部分拆開請求就好了。在web + db的兩層架構之間,也可以加一層cache,例如memcache或redis或其它cache實作,這層麼稍微花點錢。

其實,cost wise(價格方面),放cdn上面來cache大部分内容,要便宜很多很多,背景可以表示“輕松無壓力”。

<b>高可用&amp;彈性擴充</b>

接着上文繼續說,如果省錢确實可以用一台虛拟機放web server。不過如果虛機挂了那就是真的挂了,業務挂了是最不劃算的事情,一般至少2台虛機,在雲上跨不同availability zone(可用區)以防止一個可用區(通常為一個實體機房)down掉。

其次,因為你要放2個以上web server互為主備,這時候就不推薦把sql server資料庫都放在web server一起了(創業時可以這麼幹,成熟了就業務為先了)。資料庫是核心資産,肯定要做主備,最好跨az甚至跨region,分開來放。試想911時候那架飛機,不單撞走了上千條人命,也撞走了好多公司,因為當時有不少人都是把資料庫放辦公室裡的,以為樓永遠不倒……然後,大家都放雲上去了。

但是,nb的雲服務商例如aws和azure,從來就會跟你說如果你自己不做備份,隻用單執行個體,如果機器挂了他們不會對你的資料可靠性負責。因為如aws般成熟的it企業,其vp werner vogels都說過everything fails。業務可用性是要靠業主自己的架構去保障(例如備份、高可用),而不是物業去保障。難道你家客廳電視機壞了看不了世界杯還要去罵物業麼?誰讓你不在卧室也放個電視機咧(主備)?或者用筆記本看(高可用)?

關于高可用的架構,網上文章很多,我就不再贅述了。

然後,我要跟大家講一個淺顯易懂的道理:虛拟機 不等于 彈性計算。

雲計算的初衷是讓大家享受彈性計算,重點在“彈性”(elastic)。很多人把這兩個字給忘了,結果變成隻有計算了,計算就變成隻有虛拟機了。如果是這樣,每個有windows 7以上的人,因為可以安裝hyperv來做虛拟機,就都有雲計算啦!

彈性的根本,是用來解決你流量的高峰低谷時候用的資源擴容和縮容,即可以給你水準擴充(注意:此時要把資料庫剝離開來别放web server一起哦)。aws、azure、阿裡雲都給你提供了scaling service,例如在阿裡雲叫elastic scaling service(ess),配置一下規則例如cpu到多少就擴容幾台web server,挺簡單的,事情不用想太複雜,成熟雲服務商早都考慮好這點了,也是最最基本的服務。否則按照傳統思維,難道真的都要更新配置,變成以前那種機器不行就加記憶體、換更貴的cpu,走上用小型機、大型機這種老路?那還要雲計算幹嘛。

<b>總結</b>

最後點個題,綜上所述,這次“事件”從技術角度來看是個不大的問題,測試也發現實際上之前存在的卡慢現象在換了基礎雲之後依舊存在。這就尴尬了。要做好網站的優化是門長期功夫,靠堆硬體(指服務商的提供的性能)是不可取的,靠服務商來服務也是不夠的。當然,對于借機pr的做法也不認同。(個人性格,不喜勿噴)

<b>建議it之家:(1)把web和database部署分離 (2)用ess這種來擴容縮容 (3)做一下高可用。可能隻需要1周時間。</b>