node.js的常見的提高效能的幾個方式

antzone發表於2017-03-26

如果不敬意求精的話,可能沒必要在意一些小的細節,只要能夠完成任務,實現功能即可。

但是很多時候又必須要要注意細節,因為比較大型的專案,可能很小的細節就能夠影響到專案的想能,尤其是負載比較高的時候。

下面是幾個常見的能夠提高node.js效能的方式和大家分享一下。

一.避免使用同步程式碼:

node.js是單執行緒的,為了能讓一個單執行緒處理許多併發的請求,可以永遠不要讓執行緒等待阻塞,同步或長時間執行的操作。Node.js的一個顯著特徵是:它從上到下的設計和實現都是為了實現非同步。這讓它非常適合用於事件型程式。

不幸的是,還是有可能會發生同步/阻塞的呼叫。例如,許多檔案系統操作同時擁有同步和非同步的版本,比如writeFile和writeFileSync。即使用程式碼來控制同步方法,但還是有可能不注意地用到阻塞呼叫的外部函式庫。那麼,對效能的影響是極大的。

[JavaScript] 純文字檢視 複製程式碼
// Good: write files asynchronously
fs.writeFile('message.txt', 'Hello Node', function (err) {
  console.log("It's saved and the server remains responsive!");
});
 
// BAD: write files synchronously
fs.writeFileSync('message.txt', 'Hello Node');
console.log("It's saved, but you just blocked ALL requests!");

初始化log在實現時無意地包含了一個同步呼叫來將內容寫入磁碟。如果不做效能測試那麼就會很容易忽略這個問題。當以developer box中一個node.js例項來作為標準測試,這個同步呼叫將導致效能從每秒上千次的請求降至只有幾十個。

二.關閉套接字池:

node.js的http客戶端會自動地使用套接字池:預設地,它會限制每臺主機只能有5個套接字。雖然套接字的重複使用可能會讓資源的增加在控制之下,但如果需要處理許多資料來自於同一主機的併發請求時,將會導致一系列的瓶頸。在這種情況下,增大maxSockets 的值或關閉套接字池是個好主意:

[JavaScript] 純文字檢視 複製程式碼
// Disable socket pooling
var http = require('http');
var options = {.....};
options.agent = false;
var req = http.request(options)

三.不要讓靜態資源使用Node.js:

對於css和圖片等靜態資源,用標準的WebServer而不是Node.js。例如,領英移動使用的是nginx。同時還利用內容傳遞網路(CDNs),它能將世界範圍內的靜態資拷貝到伺服器上。這有兩個好處:

(1)能減少我們node.js伺服器的負載量 。

(2)CDNs可以讓靜態內容在離使用者較近的伺服器上傳遞,以此來減少等待時間。

四.在客戶端渲染:

快速比較一下伺服器渲染和客戶端渲染的區別。如果用node.js在伺服器端渲染,對於每個請求都會回送像下面這樣的HTML頁面:

[HTML] 純文字檢視 複製程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
</head>
<body>
<div class="header"> 
<img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/></div>
<div class="body">Hello John!</div>
</body>
</html>

這個下面頁面所有的內容,除了使用者的名字,其餘都是靜態內容:對於每個使用者和頁面過載內容都是一樣的。因此更有效的作法是讓Node.js僅以JSON形式返回頁面需要的動態內容。

[JavaScript] 純文字檢視 複製程式碼
{"name": "John"}

頁面的其餘部分—所有靜態的HTML標記-能放在JavaScript模板中(比如underscore.js模板):

[HTML] 純文字檢視 複製程式碼
<!DOCTYPE html>  
<html>  
<head>  
<meta charset=" utf-8">  
<meta name="author" content="http://www.softwhy.com/" />  
<title>螞蟻部落</title>
</head>
<body>
<div class="header">
  <img src="http://mobile-cdn.linkedin.com/images/linkedin.png" alt="LinkedIn"/>
</div>
<div class="body">
Hello <%= name %>!
</div>
</body>
</html>

效能的提升來自於這些地方:如第三點所說,靜態JavaScript模板能通過webserver(比如nginx)在伺服器端提供,或者用更好的CDN來實現。此外,JavaScript模板能快取在瀏覽器中或儲存在本地,所有初始頁面載入以後,唯一需要傳送給客戶端的資料就是JSON,這將是最有效果的。這個方法能極大性地減少CPU,IO,和Node.js的負載量。

五.使用gzip:

a:3:{s:3:\"pic\";s:43:\"portal/201703/26/184523ilg5l0md10ldluip.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

相關文章