來聊聊react-native應用的健康監控

監控什麼

今天咱們來聊聊如何監控你的應用程序,這裏的監控說的不是讓咱們去監控用戶,而是監控應用的健康狀態,什麼是健康狀態呢?對於後端的同窗來講,在微服務的架構下,每一個子服務是否正常工做、返回的結果是否知足預期,這些就算是健康狀態,再舉個例子,你的臺式機,對於操做系統來講,每一個硬件是否能正常的工做、工做的穩定性,這些都是須要關注的健康狀態。前端

既然咱們關心健康狀態,那麼咱們該如何衡量一個「設備」的健康狀態呢?對於上面的例子,CPU運行的溫度、硬盤讀取的速度、子服務執行的效率,這些均可以做爲健康狀態的參考標準。而對於咱們前端來講,一個服務的響應速度、某個頁面渲染的時間、外接設備是否正常運行、以及正常運行的時間比,這些均可以做爲咱們衡量一個「設備」是否健康的標準。node

上面說的了要監控什麼指標,那這些指標具體的實例又是什麼呢?因爲我主要作react-native應用的開發,我今天就基於react-native來討論一下這件事,而對於傳統的web,相對來講就簡單一些了,但具體的思路不會差太多。react

在我遇到的實際場景中,個人應用程序經常須要連接多個外接設備,例如:鍵盤、掃碼槍、各類個感應器,因此我須要時刻關注這些設備的健康狀態,一旦發現某個設備不能正常工做或者在將來的某個時刻不能正常工做,就須要立刻反饋出來,而這只是一部分,這些物理設備有着很明確的「指標」。web

另外一方面,諸如網絡狀態、電池電量,這些應用內的「指標」也須要我時刻的關注,何時處於弱網環境、何時出現低電量等各類各樣的異常狀況都會讓咱們的應用程序變得不健康。因此,咱們的目標就是圍繞着這兩塊展開監控,那麼接下來我 們說說該從什麼地方下手。redis

生命週期

將全部想要監控的服務收集到一塊兒,做爲一個總控制,而後在總控中對各個服務器的各個生命週期埋點。

一、主動式:手動的從各個生命週期中hook想要的數據,而後經過計算,收集上報。數據庫

二、被動式: 在各個生命週期中埋點,等待某一類事件的觸發。編程

但是這麼多設備,若是咱們一個個的去監控、去適配,那就和給windows系統的硬件寫驅動同樣繁雜了,這對於咱們前端開發來講工做量實在是太大了,因此爲了方便咱們進行統一的管理,和複用統一的代碼,咱們須要一個「模式」去規範和統一咱們的設備。windows

如今咱們用一個統一的class去集中監控咱們的設備,另一個問題就是衆多的設備,不管是「物理」的設備仍是「虛擬」的設備,若是咱們專門爲每一種去寫監控代碼,工做量實在是太大了,因此咱們可讓這些設備在上層表現的「一致」,爲此,咱們引入「生命週期」這個概念,在一個設備啓動、運行、暫停、卸載的各個階段,咱們均可以進行監控,不管是掃碼器,仍是網絡請求的發起,各類各樣的形態都逃不過這個步驟,因此,只要能在這個上面作好文章,那麼監控各類數據就易如反掌了。後端

如下我會從兩個方面來介紹一下我總結的「基礎」的監控項,我的認爲,不管你的項目爲了應對什麼樣的場景,下面的這些例子基本都會是「必備」的選項了,即使你的項目比個人項目更加精簡,可是下面介紹的思路也會是不錯的參考。react-native

主動式監控

上面說了這麼多,那麼咱們來具體的看看須要監控些什麼呢?

在一個項目剛上線的時候,存在着不少隱藏的問題,因此咱們須要更多的日誌去監控應用程序是否正常的運行,以及是否按照咱們自身設定的路線去執行,一旦項目穩定,一些模塊或邏輯被證明是沒有問題的了,那麼相應的咱們也要去移除一些埋點日誌,另一方面,在開始上線的時候因爲用戶量少,一旦出現線上bug,因爲缺乏案例,致使定位和分析的難度都會增大,因此,這個時候咱們就須要主動的埋一些監控點,來應對這種狀況的發生,在出現緊急bug的時候咱們能夠經過日誌點去推測和演算用戶的行爲,以及當時的狀況。

可是,說到底這些監控都是臨時的,不一個長期的監控,因此個人原則也是儘量的不去侵入到業務代碼中,不管是經過切面編程仍是高階組件封裝,都要保證這些監控代碼能夠經過一個或一組規則快速的關閉統計,解放算力。

所以,凡是主動監控都要具有自動判斷和動態策略這兩個特色,能夠動態的感知到當前的狀態,從而作出對主業務影響最小的行爲,即使監控再重要,也不能由於監控的行爲而影響業務進程的工做,這隻能是一個錦上添花行爲。

被動式監控

爲何要有被動式的監控呢?首先,有些監控的相對「獨立」的,每一次的監控點並不會100%的觸發,每次的觸發並不存在上下文或者先後的必然聯繫。也就是說,這些點的觸發都是單獨存在的,因此咱們不須要對其進行諸如計算、格式化等分析操做,也不須要保存它的上下文,好比開始、結束時間。

相對於上面介紹的主動式監控,被動式監控的代碼和邏輯都會長期的運行,由於在項目的中後期,在移除了大多數異常、性能監控後,這些僅存的代碼就成了咱們排查問題的關鍵所在了。所以,這些監控要保證自身的穩定,以及所積累的信息準確、及時,誰都不但願看到奔潰或者邏輯錯誤的警報在發生以後好久才上報出來。

那麼有哪些須要咱們作被動式的監控呢?在個人項目中,一個外接設備是否在線,用戶點擊鍵盤上某個按鈕等行爲就是一個典型的被動式監控,我不知道用戶何時去點鍵盤,我也不知道個人外接設備何時斷開,我只是須要捕獲到這個行爲的發生就能夠了。

並且對於這些監控點,咱們其實是不須要開發本身去寫代碼的,它應該存在於依賴的包中,這就避免了我屢次寫重複代碼的問題,舉個例子,我在A項目中有個對掃碼器掃描到內容的監控,而在B、C項目中我仍舊須要這個功能,那麼我就能夠再也不反覆的去寫這塊的日誌代碼了,由於它應該存在於這個掃碼器的包中,我要作的,只是提供一個logger方法而已,返回的格式、內容都不須要我去關心。

而這些經過埋點、用戶輸入、事件回調等方式收集上來的日誌,咱們都要如實的上報到遠程服務器(這裏和主動式監控有所區別,主動監控的內容能夠容許咱們本身計算、統計),由於這些都是真正的異常,之後會影響咱們debug的日誌要最大程度的保留現場。

客戶端流程圖

圖片描述

服務端

上面說了那麼多,都是基於客戶端去作的,如今咱們在客戶端已經準備好了想要的數據,那麼咱們該如何去使用他們呢?

對於發送上來的日誌,我能夠作以下三件事:

  • 監控24小時在線狀態
  • 異常指標的快速報警
  • 可視化的展現監控信息

下面咱們就圍繞這三點來設計咱們的服務端系統。

對於第一點,咱們能夠經過與客戶端的心跳包來檢查客戶端是否存活,由於在業務場景中,咱們的應用爲react-native的,因此在檢測心跳的時候就要區分是native模塊仍是js的業務模塊了,同時不少場景下存在無人使用時js業務不會上傳日誌以及在移動網絡下業務精簡日誌的狀況,所以咱們的24小時監控服務就要足夠靈活、多變。因此在報警的時候能夠經過讀取配置的方式在服務器不重啓的狀況下動態的變換監控規則。

例如什麼項目須要監控native存活,什麼項目須要監控js環境存活,何時將報警通知給何人,而且能夠通知到是什麼地方的什麼設備出了什麼故障,這些都是基礎功能。

而第二點,須要咱們作的除了包含第一點以外的功能外,還有一個異常記錄的功能,由於第二點的異常具備偶發性,而且相對於心跳包來講,日誌內容更加豐富,所以咱們能夠針對這些日誌作更多的事情,但首先就是將這些日誌分類的保存起來。同時,在第二點中存在不一樣的應用對不一樣的異常有不一樣的定義的狀況,好比說A應用認爲數據初始化的接口超時就屬於異常,而B應用則認爲即使超時也不影響,那麼就須要爲每一個應用單獨配置異常指標,從而作到分項目、分閾值的功能。

還有一些額外的拓展,因爲上面作的分項目、分閾值處理,就勢必存在一些通用異常,那麼每一個項目就應該具備繼承公共異常的功能,以及一些模板異常的設定。這些都是這個服務所須要的功能。

最後一點,在蒐集到異常以及通知到相關負責人以後,此次異常報警就算結束了嘛?固然沒有這麼簡單了,咱們能夠基於web服務來查看一些日誌的基本狀況,例如什麼項目報警最多,什麼地方報警最多,什麼時間報警最多等等圖表提供咱們查看和分析。更有甚者咱們能夠根據不一樣的報警級別給不一樣的人發送不一樣的報警內容。

最後是這個服務端自身的健壯性,因爲咱們的服務是基於nodejs來作的,所以經過pm2,我能夠很方便的在進程掛掉以後立刻恢復服務,同時爲了服務相互解耦和最大化cpu效率,經過pm2啓動腳原本將24小時離線服務、異常指標報警、日誌分析展現服務相互獨立開,併爲能夠啓動多線程的服務提供cluster模式的支持。而且將共享的數據經過redis緩存,配置經過數據庫持久化等方式來備份和保證服務的健壯與高效。

服務端流程圖

圖片描述

總結

至此,一個由客戶端+服務端的健康監控系統初步完成。它們這些服務看似相互依賴,但又相互解耦,不會形成一個環節失效致使整個系統奔潰,同時又能夠作到對正常業務最小化的侵入。

固然,這些都只是一個雛形,一個所有由js去完成的項目,相對於大公司那些完整而又系統的監控來講,僅僅只能做爲開發業務的咱們自查的一個工具。雖然有這些系統來保證咱們的項目正常、健康的運行,可是更重要的是咱們開發者本身代碼的健壯和穩定。工具作的再好,也不能替代咱們本身寫的優異的代碼。

相關文章
相關標籤/搜索