淺談 OneAPM 在 express 項目中的實踐

【編者按】OneAPM 運營團隊,近日在 github 上發現了一篇文章,特別奉獻給你們。本文做者王宇先生從2015年年初就開始使用咱們的產品,也是OneAPM 的忠實用戶。html

OneAPM 是一個優秀的性能監控平臺。爲何咱們要使用性能監控呢? 並非爲了炫耀我有多麼酷的玩具,僅僅由於咱們但願在問題發生的第一時間就能知道。 在第一時間發現問題,把問題解決於無形之中,總比出了大麻煩通宵達旦加班舒服得多。node

然而有的人喜歡說:「有些問題留着也不會有什麼影響。」但我以爲服務端的事情, 凡是冒煙的地方,終究會着火的。git

還有的人喜歡說:「個人代碼絕對不可能有 bug 。」不過這只是吹牛逼。github

廢話不說了,直接上乾貨吧。

OneAPM 的監控服務主要分如下幾塊web

使用 OneAPM 監控本身的項目,首先你須要去 OneAPM.com 註冊一個開發者帳號。api

Application Insight 應用程序監控

登陸平臺之後根據本身項目的語言選擇探針,我這裏項目是用的 express,因此選擇了 nodejs, 在 OneAPM 裏面對怎麼安裝探針寫得很詳細,大概就是在項目的目錄下運行

npm install OneAPM --registry http://npm.OneAPM.com

而後配置文件從 node_modules/OneAPM 裏面拷出來,改一下 License Key ,就這麼簡單。

咱們安裝好探針之後,過幾分鐘讓插件收集到數據,就能在面板裏面看到各類圖標。

首先須要關注的是 響應時間圖表

response time

這個圖表會對服務端耗時給一個大致印象,你們能夠發現咱們項目最慢的時候, 是發生在 8 月 18 號晚上左右,有請求大約 1.25s 才結束。紫色的佔了絕大多數, 這些都是外部服務消耗的時間。

右上角的窗口叫作 apdex

apdex

這是一個評估用戶滿意度的指標,從這個指標能夠看到用戶是否滿意咱們的響應速度, 最右上角有 1[0.5] 能夠看到咱們 100% 的用戶都滿意咱們的響應速度,小於 0.5 秒的請求, 咱們稱之爲滿意。咱們這裏是用的 OneAPM 的默認設置,小於 0.5 秒錶示滿意,0.5-2 秒是可容忍, 2秒以上則不滿意。

cpm 圖表

cpm

這個圖表表明吞吐量

咱們能夠看到項目最高的時候,大概每分鐘 80 次請求,平均每分鐘 17.88 次請求。

web事務圖表

web

這是一個很重要的圖表,在這裏咱們能看到性能最差的幾個 web 事務,咱們經過 url, 能找到代碼中對應的 controller 函數,從而找到這個接口中性能的瓶頸

咱們來仔細看一個請求吧,第一條 express/POST/api/ex... (鼠標放上去能夠顯示所有的 url, 實際上這一條是這樣的 Expressjs/POST/api/exams/signup-all)

咱們能夠點進去,查看接口的詳細狀況。

裏面有一些僅對這個接口的吞吐量,執行時間等等的圖表,具體含義和前面介紹的差很少 ,只不過考察的對象變成了惟一這一個接口。

我認爲最重要的一個圖表是 breakdown table

breakdown

這個圖表反應了咱們這個接口對外部應用(external),數據庫( database )的調用狀況。 從圖表上能夠發現,每次咱們調用這個接口,咱們會調用 37 次一個叫作 xxxxxtct.com 是 http 協議的 外部服務。執行的時間佔到了 96.88%,另外查了 2 次數據庫。分別佔 0.49% 和 0.07%

看到這裏,我們就知道怎麼優化啦~~拿我這個接口來講,這裏的瓶頸主要是卡在發送 37 次 http 請求給 xxxxxtct.com 這個地方,這個 xxxxxtct.com 實際上是咱們本身的一個子系統,若是我在子系統裏面寫一個接口,把如今 37 個請求的內容合併,這個性能問題就完美的解決了。

另外 OneAPM 的 Application Insight 還給咱們提供了,系統拓撲圖,按 web 事務查找瓶頸的功能,按 sql 查找瓶頸的功能, 外部服務的具體執行時間(這個很重要,看誰在拖咱們的後腿)以及後臺服務的監控。

最後說一下錯誤率這個 table,這是我我的的經驗

express 在拋出系統異常的時候,有可能會掛掉。下面舉2個栗子

exports.show = function(req, res) {
  a.b //a == undefined
}

拋出異常

exports.show = function(req, res) {
  request.post({
    url: xxx-service.com
  }, function(err, response, body) {
    a.b //a == undefined
  })
}

拋出異常,而後服務掛掉。

OneAPM 是被 express 程序啓起來的,算是 express 進程的一個子進程,若是 express 掛掉了, OneAPM 也跟着掛了,因此,不可能有機會發回錯誤信息。 結論是隻要在回調裏面拋出的異常,任何探針都沒有辦法收集到錯誤, 由於在這一層沒法作這件事情。

固然,咱們雖然有 pm2 這樣優秀的進程管理工具來幫咱們,掛掉以後自動重啓服務。。。 但咱們須要在第一時間得到報錯信息啊。。。。即便 pm2 的 errpr.log 裏面會保留異常, 但誰又會沒事專門盯着 error 這個日誌看呢。

針對這個問題,我本身寫了一段代碼來收集錯誤日誌,但願對你們有幫助。

var pm2 = require('pm2');
var Slack = require('slack-node');

pm2.launchBus(function(err, bus) {
  console.log('connected');

  bus.on('log:err', function(data) {
    var webhookUri = "{你的slack webhook}";
    var slack = new Slack();
    slack.setWebhook(webhookUri);

    slack.webhook({
      channel: "#general",
      username: "cq-tct",
      icon_emoji: ":ghost:",
      text: data.data
    }, function(err, response) {
      console.log(response);
    });
  });

});

把這一段保存爲 err_notifier.js 放在項目根目錄下,每次啓完服務以後運行
node err_notifier.js 這樣就能經過 slack 第一時間收到報錯了。即便服務掛掉也能發過來。

這裏用了另外一個叫作 slack 的工具,slack 是一款即時通訊的辦公協做工具,相信你們或多或少都據說過 (就是創業半年估值 11 億美圓,一年變 28 億那個傢伙)。國外相似的還有 hipchat, 國內我不太清楚。

首先去 slack 申請一個 team, 而後建立一個 room,爲 room 打開一個 webhook, 把 webhook 的地址賦值給 webhookUri, 這樣咱們不管在哪裏,只要項目報錯,就能第一時間 收到經過 slack 推送過來的錯誤日誌。

固然,你能夠把推送的工具改爲,hipchat,郵件,短信,這個隨你們高興了。 關於 pm2 的 event monitor,還有更多事情可作,你們能夠參考這裏

https://github.com/xiaoyang2022/PM2/blob/dadf0f5806536ae95636ac929155c39b8bf030bb/doc/PROGRAMMATIC.md

最後

OneAPM 雖然能夠幫你們在開發初期鋪平道路,但也不意味着由於有了監控就能夠胡做非爲 (反正項目只要冒煙了,OneAPM 一目瞭然)。

我認爲最靠譜的作法是: 嚴格遵照各類 style guide 來寫代碼 + 一個監控系統 + 100% 覆蓋率的單元測試 + 幾套集成測試 + 一套可靠的發佈流程。

寫在最後:OneAPM 很是感謝王宇先生對咱們產品的支持,將來咱們將更加努力,爲用戶提供更大的價值。

相關文章
相關標籤/搜索