若是你是一個NodeJS服務器開發工程師,確定面臨過一個問題:如何優化NodeJS服務器的性能。這個問題其實涉及到的內容是很是廣的,優化方法也是多種多樣的,若是初涉這個領域頗有可能被搞的暈頭轉向,不知道從哪裏開始優化。更不理解那些密密麻麻的優化手段背後的原理。這篇文章用測試加分析的方式來講明NodeJS服務器的運行原理,幫助讀者理清性能優化的頭緒。
chrome
服務器:NodeJS。 數據庫
服務器測試工具:Chrome、Jmeter。 性能優化
我實現了一個簡單的NodeJS服務器,這個服務器只有一個簡單的A接口。如今我但願通過一系列測試來搞清楚NodeJS服務器的運做原理從而理清如何才能提升它的性能。
服務器
我用chrome簡單的調用了一次A接口。 結果以下圖:
微信
能夠看到接口A調用的整個過程的用時是21.12ms,這其實就是服務器的接口響應時間,這是體現服務器性能的重要指標之一。但其實接口A的執行時間只須要8ms。 網絡
能夠得出結論: 接口響應時間 = 網絡傳輸時間 + 應用服務器處理時間 + 接口執行時間。因此若是你要優化接口響應時間是否是須要檢驗以上不一樣階段的耗時,使用不一樣的手段去有優化呢。
app
我使用Jmeter在20秒內不斷的重複調用接口A,測試結果以下:
異步
其中須要關注的指標有兩個Average(平均接口響應時間)是15ms和Throughput(吞吐量)是65次/秒。平均接口響應時間以前已有說明,這裏咱們看一下吞吐量。吞吐量是指服務器處理事務的效率,通常是指每秒鐘處理多少個請求。優化服務器性能其實就是優化這兩個重要的指標。工具
我使用Jmeter同時開啓了兩個線程,在20秒內不斷的重複調用接口A,測試結果以下:
性能
如今咱們來分析測試2和測試3的數據:能夠看到平均響應時間(Average)差很少沒有很大的變化。再來看看吞吐量,測試2爲64.9次/秒,測試3爲102.7次/秒。
爲何吞吐量會變大呢?其實緣由很簡單測試2中只有一個線程在調用接口A,接口返回後到接口A再一次調用這段時間內服務器是閒置狀態。在測試3中,因爲有兩個線程在調用,可以利用服務器閒置的時間。服務器閒置時間變少了,吞吐量天然上升了。
我又使用Jmeter同時開啓了10個線程,在20秒內不斷的重複調用接口A:
如今咱們來分析測試3和測試4的數據,能夠看到吞吐量(Throughput)沒有很大的變化是。再來看看平均響應時間(Average),測試3爲16ms,測試4爲88ms。
爲何吞吐量沒有變化呢?那是由於當服務器一直滿負荷工做的時候,吞吐量就達到了最大值區間,就算線程數再大也不會有大變化。
爲何平均響應時間(Average)會變大呢?這也很容易理解,當服務器滿負荷工做時,新過來的請求沒辦法及時處理就開始排隊了。因此,響應時間變大的最大緣由其實就是排隊時間變大。
能夠得出結論: 吞吐量的最大值其實就是在服務器滿負荷工做時產生的。
我把耗時8ms的接口A改爲了純異步的方法。一樣使用Jmeter同時開啓了10個線程,在20秒內不斷的重複調用接口A:
能夠看到平均響應時間(Average)又回到了15ms。再來看看吞吐量(Throughput)測試4爲109.8次/秒, 測試5爲567.0次/秒。
這是什麼緣由呢,因爲NodeJS是單線程的,當你在接口中使用了一些異步的方法好比使用數據庫或者異步文件操做來替原來的同步方法就比如解放了NodeJS主線程,每次請求節約了調用接口執行的8秒時間。
我在測試5的基礎上用了四核模式來開啓NodeJS服務進行測試:
能夠看到平均響應時間(Average)是17ms變化不大。再來看看吞吐量(Throughput)測試5爲567.0次/秒,測試6爲1081.4次/秒。
能夠看到吞吐量又翻了一倍,這是爲何呢?由於4核模式至關於啓用了4個NodeJS服務器。那爲何沒有翻4倍呢?由於服務器機器的CPU是最大4核的,因此就算4核模式運行也不能用滿4核,電腦系統還要運行。
這裏我經過一個例子和6個測試來一步一步說明NodeJS服務器的運行原理和理清性能優化的頭緒。通過這6步改動,服務器的吞吐量從剛開始的65/sec到最後的1081.4/sec,同時平均響應時間(Average)也沒有變大,已是一次不錯的優化。其實性能優化的辦法有不少,這裏主要是幫助你理清頭緒。這樣在實際工做中就能夠根據本身項目的實際需求,去思考哪裏須要優化,經過什麼方式優化,最終達到什麼效果。例如,避免使用同步代碼,能夠解放主線程。傳輸數據大的接口使用gzip能夠加快網絡傳輸速度。數據庫服務器分離能夠更好地利用CPU資源等等。