浅谈 OneAPM 在 express 项目中的实践
【編者按】OneAPM 運營團隊,近日在 github 上發(fā)現(xiàn)了一篇文章,特別奉獻給大家。本文作者王宇先生從2015年年初就開始使用我們的產(chǎn)品,也是OneAPM 的忠實用戶。
OneAPM 是一個優(yōu)秀的性能監(jiān)控平臺。為什么我們要使用性能監(jiān)控呢? 并不是為了炫耀我有多么酷的玩具,僅僅因為我們希望在問題發(fā)生的第一時間就能知道。 在第一時間發(fā)現(xiàn)問題,把問題解決于無形之中,總比出了大麻煩通宵達旦加班舒服得多。
然而有的人喜歡說:「有些問題留著也不會有什么影響?!沟矣X得服務(wù)端的事情, 凡是冒煙的地方,終究會著火的。
還有的人喜歡說:「我的代碼絕對不可能有 bug ?!共贿^這只是吹牛逼。
廢話不說了,直接上干貨吧。
OneAPM 的監(jiān)控服務(wù)主要分以下幾塊
Application Insight: 應(yīng)用程序監(jiān)控
Browser Insight: 瀏覽器客戶端監(jiān)控
Mobile Insight: 移動客戶端監(jiān)控
Infrastructure Insight: 服務(wù)器監(jiān)控
使用 OneAPM 監(jiān)控自己的項目,首先你需要去 OneAPM.com 注冊一個開發(fā)者賬號。
Application Insight 應(yīng)用程序監(jiān)控
登錄平臺以后根據(jù)自己項目的語言選擇探針,我這里項目是用的 express,所以選擇了 nodejs, 在 OneAPM 里面對怎么安裝探針寫得很詳細,大概就是在項目的目錄下運行
npm install OneAPM --registry http://npm.OneAPM.com然后配置文件從 node_modules/OneAPM 里面拷出來,改一下 License Key ,就這么簡單。
我們安裝好探針以后,過幾分鐘讓插件收集到數(shù)據(jù),就能在面板里面看到各種圖標。
首先需要關(guān)注的是 響應(yīng)時間圖表
這個圖表會對服務(wù)端耗時給一個大體印象,大家可以發(fā)現(xiàn)我們項目最慢的時候, 是發(fā)生在 8 月 18 號晚上左右,有請求大約 1.25s 才結(jié)束。紫色的占了絕大多數(shù), 這些都是外部服務(wù)消耗的時間。
右上角的窗口叫做 apdex
這是一個評估用戶滿意度的指標,從這個指標可以看到用戶是否滿意我們的響應(yīng)速度, 最右上角有 1[0.5] 可以看到我們 100% 的用戶都滿意我們的響應(yīng)速度,小于 0.5 秒的請求, 我們稱之為滿意。我們這里是用的 OneAPM 的默認設(shè)置,小于 0.5 秒表示滿意,0.5-2 秒是可容忍, 2秒以上則不滿意。
cpm 圖表
這個圖表代表吞吐量
我們可以看到項目最高的時候,大概每分鐘 80 次請求,平均每分鐘 17.88 次請求。
web事務(wù)圖表
這是一個很重要的圖表,在這里我們能看到性能最差的幾個 web 事務(wù),我們通過 url, 能找到代碼中對應(yīng)的 controller 函數(shù),從而找到這個接口中性能的瓶頸
我們來仔細看一個請求吧,第一條 express/POST/api/ex... (鼠標放上去可以顯示全部的 url, 實際上這一條是這樣的 Expressjs/POST/api/exams/signup-all)
我們可以點進去,查看接口的詳細情況。
里面有一些僅對這個接口的吞吐量,執(zhí)行時間等等的圖表,具體含義和前面介紹的差不多 ,只不過考察的對象變成了唯一這一個接口。
我認為最重要的一個圖表是 breakdown table
這個圖表反應(yīng)了我們這個接口對外部應(yīng)用(external),數(shù)據(jù)庫( database )的調(diào)用情況。 從圖表上可以發(fā)現(xiàn),每次我們調(diào)用這個接口,我們會調(diào)用 37 次一個叫做 xxxxxtct.com 是 http 協(xié)議的 外部服務(wù)。執(zhí)行的時間占到了 96.88%,另外查了 2 次數(shù)據(jù)庫。分別占 0.49% 和 0.07%
看到這里,咱們就知道怎么優(yōu)化啦~~拿我這個接口來說,這里的瓶頸主要是卡在發(fā)送 37 次 http 請求給 xxxxxtct.com 這個地方,這個 xxxxxtct.com 其實是我們自己的一個子系統(tǒng),如果我在子系統(tǒng)里面寫一個接口,把現(xiàn)在 37 個請求的內(nèi)容合并,這個性能問題就完美的解決了。
另外 OneAPM 的 Application Insight 還給我們提供了,系統(tǒng)拓撲圖,按 web 事務(wù)查找瓶頸的功能,按 sql 查找瓶頸的功能, 外部服務(wù)的具體執(zhí)行時間(這個很重要,看誰在拖我們的后腿)以及后臺服務(wù)的監(jiān)控。
最后說一下錯誤率這個 table,這是我個人的經(jīng)驗
express 在拋出系統(tǒng)異常的時候,有可能會掛掉。下面舉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}) }拋出異常,然后服務(wù)掛掉。
OneAPM 是被 express 程序啟起來的,算是 express 進程的一個子進程,如果 express 掛掉了, OneAPM 也跟著掛了,所以,不可能有機會發(fā)回錯誤信息。 結(jié)論是只要在回調(diào)里面拋出的異常,任何探針都沒有辦法收集到錯誤, 因為在這一層無法做這件事情。
當然,我們雖然有 pm2 這樣優(yōu)秀的進程管理工具來幫我們,掛掉之后自動重啟服務(wù)。。。 但我們需要在第一時間獲得報錯信息啊。。。。即使 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 放在項目根目錄下,每次啟完服務(wù)之后運行
node err_notifier.js 這樣就能通過 slack 第一時間收到報錯了。即使服務(wù)掛掉也能發(fā)過來。
這里用了另一個叫做 slack 的工具,slack 是一款即時通信的辦公協(xié)作工具,相信大家或多或少都聽說過 (就是創(chuàng)業(yè)半年估值 11 億美元,一年變 28 億那個家伙)。國外類似的還有 hipchat, 國內(nèi)我不太清楚。
首先去 slack 申請一個 team, 然后創(chuàng)建一個 room,為 room 打開一個 webhook, 把 webhook 的地址賦值給 webhookUri, 這樣我們無論在哪里,只要項目報錯,就能第一時間 收到通過 slack 推送過來的錯誤日志。
當然,你可以把推送的工具改成,hipchat,郵件,短信,這個隨大家高興了。 關(guān)于 pm2 的 event monitor,還有更多事情可做,大家可以參考這里
https://github.com/xiaoyang2022/PM2/blob/dadf0f5806536ae95636ac929155c39b8bf030bb/doc/PROGRAMMATIC.md
最后
OneAPM 雖然可以幫大家在開發(fā)初期鋪平道路,但也不意味著因為有了監(jiān)控就可以胡作非為 (反正項目只要冒煙了,OneAPM 一目了然)。
我認為最靠譜的做法是: 嚴格遵守各種 style guide 來寫代碼 + 一個監(jiān)控系統(tǒng) + 100% 覆蓋率的單元測試 + 幾套集成測試 + 一套可靠的發(fā)布流程。
寫在最后:OneAPM 非常感謝王宇先生對我們產(chǎn)品的支持,未來我們將更加努力,為用戶提供更大的價值。
總結(jié)
以上是生活随笔為你收集整理的浅谈 OneAPM 在 express 项目中的实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [JS][jQuery]清空元素html
- 下一篇: 《算法导论》学习笔记——快速排序