邵晨龍+江雪
摘要:當(dāng)前基于Node的Web應(yīng)用得到了廣泛的關(guān)注和應(yīng)用,但這類應(yīng)用增長速度之快,導(dǎo)致的產(chǎn)品化性能問題往往容易被忽視。本文主要通過動(dòng)靜分離、啟用緩存、多進(jìn)程架構(gòu)、讀寫分離四個(gè)方面來說明如何針對(duì)基于Node的Web應(yīng)用作性能提升。
關(guān)鍵詞:Node;產(chǎn)品化;性能優(yōu)化
1 引言
對(duì)于基于Node的Web應(yīng)用而言,最直接有效的提升性能的方法莫過于動(dòng)靜分離、啟用緩存、多進(jìn)程架構(gòu)和讀寫分離。一般地,提升性能遵循的原則可以拆分為:做專一的事;讓擅長的工具做擅長的事情;將模型簡化;將風(fēng)險(xiǎn)分離。
2 性能提升方法
2.1 動(dòng)靜分離
在普通的Web應(yīng)用中,Node盡管也能通過中間件來實(shí)現(xiàn)靜態(tài)文件服務(wù),但是Node處理靜態(tài)文件的能力并不算突出。因此,在Node應(yīng)用中通常是將發(fā)往服務(wù)器的請(qǐng)求分為兩種:一種是動(dòng)態(tài)服務(wù)請(qǐng)求,一種是靜態(tài)文件請(qǐng)求。將動(dòng)態(tài)服務(wù)請(qǐng)求和靜態(tài)文件請(qǐng)求分離后,Node服務(wù)器可以專注在動(dòng)態(tài)服務(wù)方面,而對(duì)于圖片、腳本、樣式表和多媒體等靜態(tài)文件都引導(dǎo)到專業(yè)的靜態(tài)文件服務(wù)器上,如Nginx或者專業(yè)的CDN,由它們來處理這個(gè)過程,就符合了“讓擅長的工具做擅長的事情”這一原則。同時(shí),專業(yè)的CDN會(huì)將靜態(tài)文件與用戶盡可能地靠近,并能夠提供更精確和高效的緩存機(jī)制。靜態(tài)文件請(qǐng)求分離后,對(duì)靜態(tài)請(qǐng)求使用不同的域名或多個(gè)域名還能消除掉不必要的Cookie傳輸和瀏覽器對(duì)下載線程數(shù)的限制。
靜態(tài)文件請(qǐng)求和動(dòng)態(tài)服務(wù)請(qǐng)求分離只是最簡單的分離,也比較容易實(shí)現(xiàn)。事實(shí)上還有更復(fù)雜的情況,比如一個(gè)網(wǎng)頁中同時(shí)存在動(dòng)態(tài)數(shù)據(jù)和靜態(tài)內(nèi)容,在Node中將內(nèi)容發(fā)送至客戶端時(shí)需要進(jìn)行字符串到Buffer的轉(zhuǎn)換,但是對(duì)于靜態(tài)內(nèi)容而言無須進(jìn)行字符串層級(jí)的替換,只要保留成Buffer即可。直接進(jìn)行Buffer傳輸可以很大程度上提升性能。是故能夠在動(dòng)態(tài)內(nèi)容中再將動(dòng)態(tài)內(nèi)容和靜態(tài)內(nèi)容分離,還能進(jìn)一步提升性能,但這種程度上的控制沒有普適性,需要較多的細(xì)節(jié)處理。
2.2 啟用緩存
提升性能其實(shí)差不多只有兩個(gè)途徑,一是提升服務(wù)的速度,二是避免不必要的計(jì)算。前者提升的性能在海量流量面前終有瓶頸,但后者卻能夠在訪問量越大時(shí)收益越多。避免不必要的計(jì)算,應(yīng)用場景最多的就是緩存。
盡管同步I/O在CPU等待時(shí)浪費(fèi)的時(shí)間較為嚴(yán)重,但是在緩存的幫助下,卻能夠消減同步I/O帶來的時(shí)間浪費(fèi)。但不管是同步I/O還是異步I/O,避免不必要的計(jì)算這條原則如果遵循得較好,性能提升是顯著的。
如今,Redis或Memcached幾乎是Web應(yīng)用的標(biāo)準(zhǔn)配置。如果產(chǎn)品需要應(yīng)對(duì)巨大的流量,啟用緩存并應(yīng)用好它,是突破系統(tǒng)性能瓶頸的關(guān)鍵。
2.3 多進(jìn)程架構(gòu)
通過多進(jìn)程架構(gòu),不僅可以充分利用多核CPU,更是可以建立機(jī)制讓Node進(jìn)程更加健壯,以保障Web應(yīng)用持續(xù)服務(wù)。由于Node是通過自由模塊構(gòu)建HTTP服務(wù)器的,不像大多數(shù)服務(wù)器端技術(shù)那樣有專有的Web容器,所以需要開發(fā)者自己處理多進(jìn)程的管理。不過在官方已經(jīng)有cluster模塊,在社區(qū)也有pm、forever、pm2這樣的模塊用于進(jìn)程管理。
2.4 讀寫分離
除了動(dòng)靜分離外,另一個(gè)較為重要的分離是讀寫分離,這主要針對(duì)數(shù)據(jù)庫而言。就任意數(shù)據(jù)庫而言,讀取的速度遠(yuǎn)遠(yuǎn)高于寫入的速度。而某些數(shù)據(jù)庫在寫入時(shí)為了保證數(shù)據(jù)一致性,會(huì)進(jìn)行鎖表操作,這同時(shí)會(huì)影響到讀取的速度。某些系統(tǒng)為了提升性能,通常會(huì)進(jìn)行數(shù)據(jù)庫的讀寫分離,將數(shù)據(jù)庫進(jìn)行主從設(shè)計(jì),主數(shù)據(jù)庫提供寫操作,從數(shù)據(jù)庫提供讀操作,這樣讀數(shù)據(jù)操作不再受到寫入的影響,有效地減輕了數(shù)據(jù)庫的壓力,也能減輕io壓力。
3 總結(jié)
通過本文描述的這些提升性能的方式,能幫助優(yōu)化基于Node的Web應(yīng)用,使得應(yīng)用更加高效、健壯。