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