(node性能優化一) API響應時間監測

jopen 10年前發布 | 20K 次閱讀 性能優化 API InfluxDB Node.js 開發

Written with vim

古語:“知己知彼,百戰不殆”,面對性能優化,哪怕不求百戰不殆,也求“死得明白”,所以在嘗試進行系統性能優化之前,先得了解系統的性能瓶頸在哪,不至于使不上勁。

我不生產知識,只是知識的搬運工,都是團隊實踐的總結。

監控選型:Grafana + Telegraf + InfluxDB

選型是團隊的架構濕安叔做的,考慮到數據實時性和靈活性,選擇了 Grafana (下文簡稱Gra) 和 InfluxDB (下文簡稱Inf), 與 oneapm 互補。

  • Inf是 time-series data 類型的數據庫,支持類sql語句查詢,適合監控數據存儲,實時分析。
  • Telegraf 是安裝于生產機的守護進程,用于埋點數據收集并轉發到Gra數據庫,并收集宿主機負載信息
  • Gra 用作數據呈現,封面截圖就來自Gra

實踐環境:

  • node v4.2.3
  • Ubuntu 14.04,15.04
  • Express v3.4.7 ~ v4.13.3

step1:安裝InfluxDB

1)下載和安裝

傳送 InfluxDB - Database Download ,直接找到 Ubuntu & Debian 章節,按照提示安裝,相比于apt-get方法,此法在國內特殊環境下靠譜些。

2)啟動:

sudo service influxdb start  

3)檢查服務是否啟動

sudo netstat -apn | grep 8086  

看到如下結果,代表啟動正常

tcp6  0  0 :::8086    :::*   LISTEN  1746/influxd  

step2:安裝Telegraf

1)下載和安裝

傳送 Telegraf - Data Collector Download ,通InfluxDB,按照提示安裝即可。

2)配置文件

安裝完成后,Linux debian and RPM packages 的配置文件位置在 /etc/opt/telegraf/telegraf.conf 打開文件后,發現 SERVICE PLUGINS 是空的,我們需要安裝 statsd ,Telegraf 命令的位置在 /opt/telegraf/telegraf

執行

/opt/telegraf/telegraf -usage statsd

輸出

# Statsd Server
[[plugins.statsd]]
  # Address and port to host UDP listener on
  service_address = ":8125"
  # Delete gauges every interval (default=false)
  delete_gauges = false
  # Delete counters every interval (default=false)
  delete_counters = false
  # Delete sets every interval (default=false)
  delete_sets = false
  # Delete timings & histograms every interval (default=true)
  delete_timings = true
  # Percentiles to calculate for timing & histogram stats
  percentiles = [90]

  # templates = [
  #     "cpu.* measurement*"
  # ]

  # Number of UDP messages allowed to queue up, once filled,
  # the statsd server will start dropping packets
  allowed_pending_messages = 10000

  # Number of timing/histogram values to track per-measurement in the
  # calculation of percentiles. Raising this limit increases the accuracy
  # of percentiles but also increases the memory usage and cpu time.
  percentile_limit = 1000

將配置示例復制到 SERVICE PLUGINS 下方。 statsd 允許其他應用通過udp的方式,以特定語法向Telegraf傳遞應用數據。3)開啟服務

sudo service telegraf start  

4)檢查服務

sudo netstat -apn | grep 8125  

輸出如下,代表啟動正常

udp6  0  0 :::8125   :::*  2696/telegraf  

step3: 應用埋點-以 Express 為示例

應用埋點,其實就是向Telegraf的Statsd服務發送數據包,端口是8125

在需找中間件的過程中,發現了 Uber express-statsd ,README.md 內給出了一種埋點方法 傳送門

推薦的方法是在路由定義時就需要確定這個API對應的Key,但是實際情況是,我參與的項目已經有幾十萬行的代碼量,大量路由已經定義過,不可能再去動這些路由。

當時嘗試的第一種方式,req.statsdKey 為 req.url,然而url是動態的,隨便加個參數就不同了,會產生大量無用key,而且并沒有按照API進行有效的聚合,尤其是GET類型的請求。

嘗試的的第二種方式,req.path 為 key,但是碰到 path url 樣式的路由就會和 req.url 發生一樣的狀況,例如 /get/user/:id 。

接著嘗試第三種方式

先脫離Express,回到最基礎 node 內置模塊 http,以前我們要開啟一個http服務器,會這樣書寫

'use strict';  
var http = require('http');

http.createServer(function(req,res){  
  res.writeHead(200,{'Content-Type':'text/html; charset=utf-8'});
  /**
    中間對URL做判斷,輸出不同結果;判斷的過程其實就是Express的route
  */
  res.end(req.url + ' at time ' + Date.now() + ' \n');
}).listen(9002);

所以, var app = express() ,如果去看app的類型,其實就是個Function,我們在app上綁定上一堆中間件后,最后會執行這么一句

http.createServer(app).listen(PORT);  

所以嘗試把焦點放到 Express 的路由機制上,假設 Express 最后處理了一個請求并且有返回,那么在請求結束的時候,req 對象上應該會存有匹配到的路由的信息,因為路由信息是確定的,所以可以作為key,而且可以保證請求按照API進行聚合。

首先確定,一次請求在什么時候結束,查閱文檔發現,http 模塊內 的res 對象有 finish,close,error 事件,用之。

再去獲取 req 對象上的路由信息,通過 debug 模式發現了 Express 在 req 對象上綁定了 route 對象,保存了請求匹配的路由信息。

綜上,改寫了 express-statsd-route 這個模塊,具體使用方法可查看項目README。

檢查埋點是否成功

Command shell 連接到InfluxDB

influx  

在shell內執行

# 選擇 telegraf 數據庫
USE telegraf  
# 顯示所有統計字段,檢查埋點key是否存入
SHOW MEASUREMENTS  

step4:安裝Grafana

傳送 Installing on Debian / Ubuntu

1)開啟服務

配置位置: /etc/grafana/grafana.ini

sudo service grafana-server start  

命令執行成功后,將在 3000 端口開啟http服務,瀏覽器訪問 http://your_ip:3000

2)添加InfluxDB支持

直接使用系統默認帳號 admin/admin 登入系統,添加 Data Sources InfluxDB 。 配置完畢后,添加一個DashBoard,按照提示選擇需要呈現的數據和緯度。

后續

完成上述操作后,稍作配置就可以得到類似封面圖的效果啦。

接下來

  • 針對外部服務的性能消耗統計
  • 整理一些 Grafana 針對 InfluxDB 的常用統計語句

來自: http://f2e.souche.com/blog/nodexing-neng-you-hua-apixiang-ying-shi-jian-jian-ce/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!