JavaScript架構(gòu)前端不能沒(méi)有監(jiān)控系統(tǒng)原因
監(jiān)控系統(tǒng)
提到監(jiān)控系統(tǒng),大部分同學(xué)首先想到的是后端監(jiān)控。很明顯,比如檢測(cè)服務(wù)器性能,數(shù)據(jù)庫(kù)性能,API 的訪問(wèn)流量,以及各種服務(wù)的運(yùn)行情況等等,都與后端息息相關(guān)。而前端更多承擔(dān)的是 UI 展現(xiàn)的角色,主要關(guān)注頁(yè)面怎么排版設(shè)計(jì),好像沒(méi)什么需要監(jiān)測(cè)的地方,因此一直以來(lái)都沒(méi)有涉及到監(jiān)控的概念。
于是呢大家就一致認(rèn)為:只要后端穩(wěn)定可控,應(yīng)用就是穩(wěn)定可控的,可實(shí)際情況真的是這樣嗎?
近年來(lái),前端發(fā)展日益迅猛,得益于 JavaScript 的持續(xù)進(jìn)化和瀏覽器功能的不斷增強(qiáng),前端能做到的事情越來(lái)越多,相應(yīng)的前端應(yīng)用的復(fù)雜度也越來(lái)越高。以前我們壓根不會(huì)遇到的問(wèn)題,現(xiàn)在蹭蹭蹭的一股腦都冒出來(lái)了。
舉個(gè)例子,小明是個(gè)前端程序員,有一天用戶(hù)反饋某頁(yè)面某按鈕點(diǎn)了沒(méi)有反應(yīng)。小明立刻找到那個(gè)按鈕,輕輕一點(diǎn),咦?正常的呀。然后小明又用了幾個(gè)不同的賬號(hào)測(cè)試,依然是正常的。這下可把小明難倒了。
怎么辦?我相信全天下的前端程序員們遇到奇怪問(wèn)題的反應(yīng)是一樣的。小明這樣告訴用戶(hù):可能是瀏覽器緩存問(wèn)題,不行強(qiáng)制刷新一下,或者退出登錄試試? 用戶(hù)按照小明的建議操作一番,果然奏效!于是給小明發(fā)來(lái)了一連串的“感謝 ??”。小明尷尬一笑,連忙回復(fù)“小意思”。
過(guò)了兩天,又有一個(gè)用戶(hù)反饋了同樣的問(wèn)題。小明又祭出了上面的萬(wàn)能解決大法,依然奏效??墒菃?wèn)題真的解決了嗎?沒(méi)有??!然而小明嘗試過(guò)很多遍都無(wú)法復(fù)現(xiàn)異常,可能原因有很多,比如:
- 數(shù)據(jù)問(wèn)題,可能取不到某個(gè)屬性
- 前端問(wèn)題,JS 代碼執(zhí)行異常
- 接口問(wèn)題,可能接口無(wú)響應(yīng),或沒(méi)有返回預(yù)期的值
然而正常情況下是沒(méi)有問(wèn)題的,小明多次測(cè)試也都正常,一定是在某種特定場(chǎng)景下才會(huì)出現(xiàn)這個(gè)問(wèn)題,但是我們無(wú)法判斷,捕捉不到。
像這類(lèi) Bug 潛伏在我們的系統(tǒng)中,仿佛地雷一樣,指不定什么時(shí)候就會(huì)爆。最尷尬的是即便它爆了我們也很難發(fā)現(xiàn),這就導(dǎo)致我們的“排雷行動(dòng)”困難重重。
某個(gè)陽(yáng)光明媚的下午,小明坐在馬桶上思考人生。突然腦海中一道靈光閃過(guò),小明想到:“如果在用戶(hù)觸發(fā)異常的那一刻,系統(tǒng)能自動(dòng)獲取到異常的數(shù)據(jù)并保存起來(lái),然后在后臺(tái)的某個(gè)地方能看到這些數(shù)據(jù),我不就可以立刻找到錯(cuò)誤原因了嗎?”
小明一拍大腿,對(duì)呀!我怎么沒(méi)有早點(diǎn)想到呢?這樣的話(huà),只要發(fā)生異常我們就能自動(dòng)捕獲到異常數(shù)據(jù),如果再遇到線上報(bào)錯(cuò),我們不需要用戶(hù)反饋,自己就可以發(fā)現(xiàn),而且能馬上定位錯(cuò)誤原因,這不是一舉兩得?
我相信許多前端前輩們也曾經(jīng)被上述的問(wèn)題所困擾,然后也像小明一樣,慢慢的有了這個(gè)思路:“將報(bào)錯(cuò)時(shí)的異常數(shù)據(jù)存下來(lái)供后續(xù)排查”。在這個(gè)思路不斷實(shí)踐的過(guò)程中,逐漸演變成了今天的前端監(jiān)控。
當(dāng)然了,今天的前端監(jiān)控并不僅僅是監(jiān)控異常數(shù)據(jù),任何有利于產(chǎn)品分析的數(shù)據(jù)都可以加入監(jiān)控。所以我認(rèn)為前端監(jiān)控,就是指采集用戶(hù)使用系統(tǒng)過(guò)程中產(chǎn)生的關(guān)鍵數(shù)據(jù),存儲(chǔ)到數(shù)據(jù)庫(kù),后續(xù)可以查找和分析,這樣的整套實(shí)現(xiàn)就被稱(chēng)為前端監(jiān)控系統(tǒng)。
前端監(jiān)控具體能解決什么問(wèn)題?
上面用一個(gè)例子推導(dǎo)出前端監(jiān)控出現(xiàn)的背景,粗略的說(shuō)了下它如何追蹤線上報(bào)錯(cuò)問(wèn)題,大家應(yīng)該初步了解了前端監(jiān)控的意義?,F(xiàn)在我們把目光聚焦在項(xiàng)目上,再詳細(xì)探究一下它具體能解決哪些問(wèn)題。
異常報(bào)錯(cuò)問(wèn)題
首先就是異常報(bào)錯(cuò)的問(wèn)題。就如例子中的場(chǎng)景一樣,線上發(fā)生異常,有時(shí)候我們難以復(fù)現(xiàn),甚至如果沒(méi)有用戶(hù)反饋,我們都不知道有這個(gè)問(wèn)題,這樣就給用戶(hù)傳遞了一種我們的產(chǎn)品很不穩(wěn)定的感覺(jué)。因此前端監(jiān)控是線上產(chǎn)品穩(wěn)定和異常及時(shí)反饋的非常關(guān)鍵的保障。
當(dāng)然了,除了前端的異常,我們同樣可以捕獲 接口異常。有的時(shí)候前端程序員們自嘲自己是“背鍋俠”,產(chǎn)品,測(cè)試,用戶(hù),遇到問(wèn)題首先找前端,不管是不是前端的問(wèn)題,前端先頂,再花時(shí)間定位錯(cuò)誤。有的時(shí)候領(lǐng)導(dǎo)脾氣不好,上來(lái)先劈頭蓋臉一頓罵,卑微前端也不敢說(shuō)話(huà),因?yàn)樯秵?wèn)題得排查后才清楚,結(jié)果排查完后是接口的問(wèn)題,白挨了一頓罵,心里就非常不爽。
但是如果有了前端監(jiān)控,我們就能馬上拿到異常發(fā)生時(shí)的錯(cuò)誤信息,頁(yè)面,地址,參數(shù)等,什么問(wèn)題一查便知。下一次遇到線上事故,前端就可以從容不迫客觀公正的說(shuō)這是哪一方的問(wèn)題。如果遇到甩鍋行為,前端也能勇敢說(shuō)不,畢竟我證據(jù)在手,豈容你說(shuō)吼就吼?
性能檢測(cè)問(wèn)題
追蹤異常是前端監(jiān)控最實(shí)用的地方,但不光如此,性能監(jiān)控 也是非常關(guān)鍵的部分。
當(dāng)下的前端工程體量很大,如果代碼質(zhì)量不高,或者項(xiàng)目架構(gòu)設(shè)計(jì)不合理,很容易遇到性能問(wèn)題。性能問(wèn)題比如首屏加載時(shí)間,頁(yè)面是否卡頓,白屏,資源重復(fù)請(qǐng)求等,可以通過(guò)數(shù)據(jù)采集,比如計(jì)算渲染時(shí)間,請(qǐng)求接口數(shù)量,請(qǐng)求資源總量等,對(duì)某個(gè)頁(yè)面進(jìn)行監(jiān)控,及時(shí)發(fā)現(xiàn)性能問(wèn)題。
那么除了可以“解決問(wèn)題”,前端監(jiān)控還有哪些價(jià)值?
運(yùn)營(yíng)反饋工具
其實(shí)前端監(jiān)控除了可以幫助程序員不斷優(yōu)化和完善應(yīng)用,對(duì)產(chǎn)品和運(yùn)營(yíng)同學(xué)有同樣不可或缺的作用。具體來(lái)說(shuō)就是通過(guò)“埋點(diǎn)監(jiān)控”來(lái)收集用戶(hù)的行為數(shù)據(jù),則可以對(duì)線上產(chǎn)品的使用情況作出統(tǒng)計(jì)分析,比如整體的 PV/UV,某個(gè)功能的訪問(wèn)量,訪問(wèn)時(shí)段,點(diǎn)擊率等等數(shù)據(jù)。這些數(shù)據(jù)可以幫助產(chǎn)品和運(yùn)營(yíng)了解實(shí)際情況,進(jìn)而改進(jìn)產(chǎn)品功能。
這些行為數(shù)據(jù)的收集,可以非常精準(zhǔn)的描繪出某個(gè)功能或者某個(gè)人的實(shí)際使用情況。當(dāng)然采集的數(shù)據(jù)量也要比異常數(shù)據(jù)大的多。相比來(lái)說(shuō),異常監(jiān)控是只有發(fā)生異常才會(huì)收集數(shù)據(jù),而行為數(shù)據(jù)則是,只要用戶(hù)使用我們的產(chǎn)品,與產(chǎn)品發(fā)生交互,理論上這些數(shù)據(jù)都要收集起來(lái)。
當(dāng)然監(jiān)控是多方面的,收集哪些數(shù)據(jù)視情況而定??傊阆肓私猱a(chǎn)品的任何情況,都可以通過(guò)設(shè)計(jì)采集規(guī)則然后收集數(shù)據(jù)來(lái)實(shí)現(xiàn),這方面是非常靈活的,并不僅僅限于大家熟知的那幾個(gè)指標(biāo)。
為什么要選擇自研?
前端監(jiān)控發(fā)展到現(xiàn)在,必然會(huì)有成熟的第三方平臺(tái)。目前國(guó)內(nèi)最常用的有三個(gè):
- sentry
- webfunny
- fundebug
首先 sentry 和 fundebug 這兩個(gè)平臺(tái)是付費(fèi)的,而且你的數(shù)據(jù)越多費(fèi)用越高,相當(dāng)于是數(shù)據(jù)托管平臺(tái)。webfunny 雖然可以私有化部署,但是它的功能是固定的,沒(méi)法改代碼,這就是它的缺點(diǎn):不夠靈活,無(wú)法定制功能。
所以目前雖然市面上已經(jīng)有成熟的監(jiān)控系統(tǒng),但依然有很多團(tuán)隊(duì)選擇自研。一是數(shù)據(jù)可以保存在自己的服務(wù)器上,不用另外花錢(qián);二是靈活性強(qiáng),可以自定義功能,比如你可以在觸發(fā)異常時(shí),接入自己的釘釘或企業(yè)微信消息推送,這就需要你的監(jiān)控系統(tǒng)靈活性很高。
還有我們上面說(shuō)的,自定義采集規(guī)則。我認(rèn)為這個(gè)是最重要的原因。不同規(guī)則采集到的數(shù)據(jù)不一樣,因此第三方標(biāo)準(zhǔn)的采集規(guī)則可能并不符合你公司的需求。比如有的公司需要獲取設(shè)備標(biāo)識(shí)作為唯一 ID,有的公司卻需要用戶(hù)標(biāo)識(shí)。這是由業(yè)務(wù)決定的,每個(gè)公司都不一樣。
我司前端組就是自研前端監(jiān)控平臺(tái)。優(yōu)勢(shì)就是可以自定義自己的采集規(guī)則,設(shè)計(jì)自己的數(shù)據(jù)庫(kù)存儲(chǔ)字段,數(shù)據(jù)都保存在自己的平臺(tái),靈活性和可靠性都非常高,能滿(mǎn)足自己的多樣性需求。
自研前端監(jiān)控的技術(shù)棧
先上結(jié)論,我司的前端監(jiān)控是前端組自己搞的,所以技術(shù)棧是 React + Node.js + MongoDB。
這是一個(gè)比較常規(guī)的技術(shù)方案,前端自己搞嘛,所以技術(shù)棧都以 JS 為主。同時(shí)這也是前端比較能琢磨明白的東西,算是一個(gè)標(biāo)準(zhǔn)方案吧。
其中,Node.js 部分我們使用 express
框架寫(xiě)接口,接口總體分兩大類(lèi),就是 寫(xiě)入 和 查詢(xún)統(tǒng)計(jì),作用呢就是前端采集到數(shù)據(jù)之后,要通過(guò)調(diào)用接口存儲(chǔ)。之后在監(jiān)控面版上,也要通過(guò)接口將數(shù)據(jù)查詢(xún)展現(xiàn)出來(lái)。
接口的背后就是 MongoDB
數(shù)據(jù)庫(kù),作用就是存儲(chǔ)我們采集到的數(shù)據(jù)。為什么選擇 MongoDB 呢?最主要的原因就是它的寫(xiě)入性能非常高,寫(xiě)入速度非??臁I厦嫖覀冋f(shuō),監(jiān)控系統(tǒng)在采集行為數(shù)據(jù)的時(shí)候,寫(xiě)入非常頻繁,那么對(duì)寫(xiě)入性能的要求就非常高,反觀查詢(xún)反而要求不那么高。
這里也有比較難啃的點(diǎn),就是采集到大量的數(shù)據(jù)之后,我們需要各個(gè)維度的統(tǒng)計(jì)分析。比如:
- 某個(gè)時(shí)間段用戶(hù)的訪問(wèn)次數(shù)和訪問(wèn)時(shí)長(zhǎng)排行
- 某個(gè)時(shí)間段頁(yè)面的訪問(wèn)頻率和停留時(shí)間排行
- 某個(gè)時(shí)間段接口報(bào)錯(cuò)的次數(shù)以及占比統(tǒng)計(jì)
這些比較復(fù)雜的查詢(xún)統(tǒng)計(jì),主要用到 MongoDB 的聚合查詢(xún)。前端寫(xiě)個(gè)基本的分組統(tǒng)計(jì)還行,這類(lèi)復(fù)雜查詢(xún)我們就捉襟見(jiàn)肘了。怎么辦呢?我們用很長(zhǎng)一段時(shí)間啃掉了 MongoDB 聚合查詢(xún)的所有文檔,按照需求一個(gè)一個(gè)找函數(shù),看哪個(gè)能實(shí)現(xiàn),幾乎把所有聚合函數(shù)都翻了一遍。
接口做完,最后用 React 實(shí)現(xiàn)一個(gè)管理后臺(tái),將數(shù)據(jù)以圖表,表格的形式展示出來(lái),就可以實(shí)時(shí)看到線上產(chǎn)品的使用情況了。
當(dāng)然還有一步,就是寫(xiě)一個(gè)對(duì)接釘釘或企業(yè)微信的通知接口,在觸發(fā)異常的時(shí)候發(fā)起通知,讓我們能及時(shí)知道異常情況。我們的通知是這樣:
這個(gè)信息就能比較全面的看出來(lái)是哪里出了問(wèn)題,如果看更詳細(xì)的錯(cuò)誤再去異常面板去找:
總之首先對(duì)接口異常全面監(jiān)控,確認(rèn)數(shù)據(jù)沒(méi)問(wèn)題之后我們?cè)偾岸巳ヅ挪椋侍岣吡?,鍋也少背了,這不是兩全其美嗎?
最后我們自研的這個(gè)小系統(tǒng)在產(chǎn)品上線后發(fā)揮了很大的作用,受到了老板的表?yè)P(yáng),這樣讓我們受到了鼓舞,繼續(xù)完善它~
更多關(guān)于前端監(jiān)控系統(tǒng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript中Array數(shù)組常用方法(附上相應(yīng)的用法及示例)
這篇文章主要給大家介紹了關(guān)于JavaScript中Array數(shù)組常用方法,文中附上相應(yīng)的用法及示例,需要的朋友可以參考下2024-01-01JavaScript中的ArrayBuffer詳細(xì)介紹
這篇文章主要介紹了JavaScript中的ArrayBuffer詳細(xì)介紹,本文講解了Array 在內(nèi)存中的堆棧模型、原始緩沖區(qū)的創(chuàng)建、數(shù)據(jù)化數(shù)組、DataView對(duì)象、XHR2 中的 ArrayBuffer等內(nèi)容,需要的朋友可以參考下2014-12-12BootStrap Validator 版本差異問(wèn)題導(dǎo)致的submitHandler失效問(wèn)題的解決方法
這篇文章主要介紹了BootStrap Validator 版本差異問(wèn)題導(dǎo)致的submitHandler失效問(wèn)題的解決方法,下面通過(guò)本文給大家詳細(xì)說(shuō)明一下,需要的朋友可以參考下2016-12-12真正好用的js驗(yàn)證上傳文件大小的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇真正好用的js驗(yàn)證上傳文件大小的簡(jiǎn)單方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10用js限制網(wǎng)頁(yè)只在微信瀏覽器中打開(kāi)(或者只能手機(jī)端訪問(wèn))
這篇文章主要介紹了用js限制網(wǎng)頁(yè)只在微信瀏覽器中打開(kāi),很多電影站也是這么限制的,原因你懂的,需要的朋友可以參考下2020-01-01JavaScript仿靜態(tài)分頁(yè)實(shí)現(xiàn)方法
這篇文章主要介紹了JavaScript仿靜態(tài)分頁(yè)實(shí)現(xiàn)方法,可實(shí)現(xiàn)模擬靜態(tài)效果的分頁(yè)功能,并且可以控制分頁(yè)的字符數(shù),使用時(shí)可根據(jù)情況進(jìn)行相應(yīng)的字段修改即可,非常靈活實(shí)用,需要的朋友可以參考下2015-08-08javascript溫習(xí)的一些筆記 基礎(chǔ)常用知識(shí)小結(jié)
在電腦上找到多年前的javascript的一些小筆記,因?yàn)橐獙⒐P記本上面的文件整理一下, 不用的刪除掉, 所以將此篇筆記再發(fā)布一下,存檔到自己的博客吧, 電腦上的文件就刪除了2011-06-06