Prometheus在B端門店回收系統(tǒng)中的應(yīng)用
1 為什么要使用Prometheus
1.1 背景
- 回收系統(tǒng)本質(zhì)做的是服務(wù)平臺(tái)。對(duì)外交互多,例如與渠道商、回收商的接口交互。因此與回收商接口的交互情況需要記錄。
 - 回收系統(tǒng)的內(nèi)部是通過大量MQ異步驅(qū)動(dòng)運(yùn)行的,復(fù)雜性很高。某一個(gè)MQ執(zhí)行異常很容易引起流程中斷。因此記錄MQ的消費(fèi)情況也很重要。
 
1.2 當(dāng)前系統(tǒng)存在的問題
- 主動(dòng)發(fā)現(xiàn)問題的能力不足。歷史接入了一些企微通知,但數(shù)量不足,場(chǎng)景少,覆蓋面窄。針對(duì)一些發(fā)生率不是很高的場(chǎng)景,很容易漏掉。系統(tǒng)需要實(shí)時(shí)掌握運(yùn)行狀態(tài),減少問題響應(yīng)時(shí)間。
 - 單純使用企微通知報(bào)警,雖然也可以對(duì)關(guān)鍵場(chǎng)景進(jìn)行提示,但維度單一,缺少圖形不直觀。報(bào)警之前不成體系,沒有聯(lián)系,不能直觀的展示業(yè)務(wù)的執(zhí)行情況。并且報(bào)警數(shù)量稍微一多,容易引起消息轟炸,丟失關(guān)鍵信息。
 - 排查問題時(shí)缺少輔助工具,耗時(shí)長。
 
2 Prometheus簡介
圖片
2.1 核心組成部分
2.1.1 Prometheus server
- 核心組件,負(fù)責(zé)抓取、存儲(chǔ)和查詢指標(biāo)數(shù)據(jù),提供API以供訪問。
 - Prometheus Server本身就是一個(gè)時(shí)序數(shù)據(jù)庫,將采集到的監(jiān)控?cái)?shù)據(jù)按照時(shí)間序列的方式存儲(chǔ)在本地磁盤當(dāng)中。
 - 內(nèi)置的UI界面,通過這個(gè)UI可以直接通過PromQL實(shí)現(xiàn)數(shù)據(jù)的查詢以及可視化。
 
2.1.2 Exporter
- Prometheus插件或獨(dú)立組件,負(fù)責(zé)抓取指定服務(wù)或系統(tǒng)的性能指標(biāo)數(shù)據(jù)。
 - Prometheus原理是通過 HTTP 協(xié)議周期性抓取被監(jiān)控組件的狀態(tài),輸出這些被監(jiān)控的組件的 Http 接口為 Exporter。
 - Exporter將監(jiān)控?cái)?shù)據(jù)采集的端點(diǎn)通過HTTP服務(wù)的形式暴露給Prometheus Server,將其公開為HTTP端點(diǎn)或指定的格式。
 - Prometheus server通過輪詢或指定的抓取器從Exporter提供的Endpoint端點(diǎn)中提取數(shù)據(jù)。
 
2.1.3 Alertmanager
- 在Prometheus Server中支持基于PromQL創(chuàng)建告警規(guī)則,如果滿足PromQL定義的規(guī)則,就會(huì)產(chǎn)生一條告警。
 - Prometheus告警管理器組件,負(fù)責(zé)管理告警規(guī)則、通知和報(bào)警策略的設(shè)置,提供第一類和第二類警報(bào)的分類管理服務(wù)PushGateway。
 - Prometheus數(shù)據(jù)采集基于Pull模型進(jìn)行設(shè)計(jì),在網(wǎng)絡(luò)環(huán)境必須要讓Prometheus Server能夠直接與Exporter進(jìn)行通信。
 - 當(dāng)這種網(wǎng)絡(luò)需求無法直接滿足時(shí),就可以利用PushGateway來進(jìn)行中轉(zhuǎn)。
 - 通過PushGateway將內(nèi)部網(wǎng)絡(luò)的監(jiān)控?cái)?shù)據(jù)主動(dòng)Push到Gateway當(dāng)中。
 - Prometheus Server則可以采用同樣Pull的方式從PushGateway中獲取到監(jiān)控?cái)?shù)據(jù)
 
2.1.4 Service Discovery
- 服務(wù)發(fā)現(xiàn)功能,動(dòng)態(tài)發(fā)現(xiàn)待監(jiān)控的Target,完成監(jiān)控配置的重要組件。
 
2.2 四種上報(bào)類型
2.2.1 Counter
遞增的整數(shù)型指標(biāo),用于表示累計(jì)數(shù)量。只能增加,不能減少,一般用于統(tǒng)計(jì)請(qǐng)求次數(shù)、錯(cuò)誤次數(shù)等場(chǎng)景。
2.2.2 Gauge
是一個(gè)可變的數(shù)值指標(biāo),用于表示某個(gè)瞬時(shí)值??勺兇笞冃?,一般用于表示當(dāng)前連接數(shù)、溫度等持續(xù)變化指標(biāo)。
2.2.3 Histogram
可以將事件按照不同的桶進(jìn)行分組,用來觀察指標(biāo)在各個(gè)不同區(qū)間范圍的分布情況,一般用于分析請(qǐng)求延遲,操作響應(yīng)時(shí)間。
2.2.4 Summary
與Histogram類似,區(qū)別在于Histogram存儲(chǔ)的是數(shù)據(jù),Summary直接存儲(chǔ)的就是百分位,本質(zhì)上并沒有什么區(qū)別,通過Histogram也可以計(jì)算出百分位。
3 Prometheus如何保障業(yè)務(wù)系統(tǒng)的穩(wěn)定運(yùn)行
3.1 監(jiān)控核心業(yè)務(wù)數(shù)據(jù)保證系統(tǒng)穩(wěn)定性
3.1.1 監(jiān)控回收訂單的數(shù)量
圖片
通過統(tǒng)計(jì)監(jiān)控某段時(shí)間的回收單的創(chuàng)建數(shù)量,可以做以下幾個(gè)方面的數(shù)據(jù)分析和預(yù)警:
- 分析需求的有效性與重要性。以接入 9906001 渠道為例,投入人力與時(shí)間資源多,訂單卻極少,未體現(xiàn)價(jià)值,若長期如此,該需求低效或無效。而 9902001 渠道訂單量很多,說明渠道很重要,進(jìn)行相關(guān)業(yè)務(wù)開發(fā)時(shí)需確保升級(jí)可靠性。
 - 進(jìn)行數(shù)據(jù)對(duì)比,9902001 渠道持續(xù)擁有高訂單量,與訂單量極低的渠道形成鮮明對(duì)比,為業(yè)務(wù)和產(chǎn)品指明不同運(yùn)營策略方向。
 - 設(shè)立訂單突增或掉零預(yù)警機(jī)制。如在雙 11、618 大促時(shí)提前介入監(jiān)控系統(tǒng)穩(wěn)定性。但是對(duì)于渠道商回收業(yè)務(wù),因外部活動(dòng)或新機(jī)型發(fā)售不可預(yù)知,訂單突增時(shí)預(yù)警,技術(shù)介入查看系統(tǒng)狀態(tài)確保穩(wěn)定;渠道長時(shí)間無訂單也預(yù)警排查系統(tǒng)問題。
 
3.1.2 監(jiān)控回收訂單創(chuàng)建失敗
圖片
通過監(jiān)控關(guān)鍵業(yè)務(wù)流程失?。?/p>
- 可快速發(fā)現(xiàn)線上問題并及時(shí)排查解決,避免影響用戶體驗(yàn)與業(yè)務(wù)運(yùn)行,不再像以往等業(yè)務(wù)反饋才行動(dòng)。
 - 業(yè)務(wù)需求上線時(shí)觀察對(duì)核心業(yè)務(wù)的影響,若回收單創(chuàng)建大量失敗,可能上線有問題,需排查是否回滾。
 
3.2 提高故障響應(yīng)和處理效率,保證系統(tǒng)穩(wěn)定性
3.2.1 監(jiān)控調(diào)用回收商接口異常
圖片
圖片
業(yè)務(wù)系統(tǒng)與外部系統(tǒng)交互的過程中,失敗的原因是多種多樣的。有可能是網(wǎng)絡(luò)問題,外部接口的問題或者業(yè)務(wù)系統(tǒng)代碼邏輯的問題。
監(jiān)控回收商接口異常及其原因,可快速定位問題根源。若因外部系統(tǒng)所致,及時(shí)反饋給外部系統(tǒng);若為業(yè)務(wù)系統(tǒng)代碼問題,可依據(jù)簡要問題信息在日志中搜索報(bào)錯(cuò),借助詳細(xì)日志定位解決問題。
注:在進(jìn)行指標(biāo)監(jiān)控時(shí),防止監(jiān)控的指標(biāo)的tag過多,轉(zhuǎn)轉(zhuǎn)這邊限制為500。
例如在監(jiān)控調(diào)用回收商接口異常原因指標(biāo)時(shí),將異常進(jìn)行歸類,從而保證了tag不會(huì)過多。
//調(diào)用外部系統(tǒng)方法
public <T, R> R execute(String priceSource, String actionCode, T bodyParam, Class<R> respsonseDataClazz) {
        try {
            //.....讀取配置,組裝請(qǐng)求url等邏輯
            try {
              //......發(fā)起請(qǐng)求
            } catch (ResourceAccessException e) {
                //捕獲超時(shí)異常,拋出重試異常
                log.error("報(bào)價(jià)方接口請(qǐng)求超時(shí)或異常,將重試,exception:{}", ExceptionUtils.getStackTrace(e));
                throw new RetryException("報(bào)價(jià)方接口請(qǐng)求超時(shí)或異常", e);
            }
            if (HttpStatus.OK.value() != responseEntity.getStatusCode().value()) {
                log.info("priceSourceApi接口httpCode非200,httpCode:{}", responseEntity.getStatusCode().value());
                throw new RetryException("priceSourceApi調(diào)用失敗: " + responseEntity.getStatusCode().value());
            }
            BaseResp baseResp = responseEntity.getBody();
            if (Objects.isNull(baseResp)) {
                throw new PriceSourceApiException("priceSourceApi返回值為空");
            }
           //....
            String respCode = baseResp.getCode();
            //根據(jù)code判斷是否重試
            if (!priceSourceApiAction.getSuccessCode().equals(respCode)) {
                throw new RetryException("priceSourceApi調(diào)用失敗: " + baseResp.getMsg());
            }
            //.......
            return o;
        } catch (Exception e) {
            log.error("execute Api PriceSource fail for priceSource: {}, action: {}", priceSource, actionCode, 
            throw new HunterErrorException("調(diào)用回收商接口失敗",e);
        } finally {
            // 記錄全部請(qǐng)求數(shù)
            long usingTime = System.currentTimeMillis() - startTime;
            String metricsName = PrometheusMetricsEnum.OUTER_RECYCLER_HANDLE_INTER2_TOTAL.getName() + priceSource;
            MetricsMonitor.recordOne(metricsName, actionCode, usingTime);
        }
    }3.3 不同監(jiān)控指標(biāo),監(jiān)控力度不同
當(dāng)我們監(jiān)控不同指標(biāo)時(shí),需要根據(jù)指標(biāo)的重要性,設(shè)置不同的報(bào)警規(guī)則。
例如創(chuàng)建回收單失敗和調(diào)用回收商接口報(bào)錯(cuò)的指標(biāo)的重要性不同。對(duì)于創(chuàng)建回收單業(yè)務(wù)來說,影響的是外部渠道調(diào)用接口可靠性的,不能有過多報(bào)錯(cuò),且接口是否重試也是由外部渠道控制的,因此我們要保證接口的可靠性,有問題要及時(shí)處理解決。但是對(duì)于調(diào)用回收商的接口,業(yè)務(wù)系統(tǒng)有重試機(jī)制,調(diào)用失敗會(huì)自行重試,且對(duì)于外部渠道是無感知的,不影響外部渠道調(diào)用業(yè)務(wù)接口的可靠性。所以對(duì)于創(chuàng)建回收單失敗指標(biāo)來說,我們報(bào)警監(jiān)控配置是一分鐘內(nèi)有一個(gè)失敗就會(huì)發(fā)送報(bào)警通知。但是對(duì)于調(diào)用回收商接口報(bào)錯(cuò)的指標(biāo),我們報(bào)警配置是十分鐘內(nèi)有五次錯(cuò)誤才會(huì)發(fā)送報(bào)警通知。
3.4 監(jiān)控遠(yuǎn)程調(diào)用QPS和耗時(shí)保證系統(tǒng)穩(wěn)定性
3.4.1 監(jiān)控遠(yuǎn)程調(diào)用耗時(shí)為技術(shù)方案提供依據(jù)
圖片
SCF框架是轉(zhuǎn)轉(zhuǎn)自己開發(fā)的遠(yuǎn)程調(diào)用框架,類似于Dubbo。
設(shè)計(jì)需求實(shí)現(xiàn)時(shí)需調(diào)用不同業(yè)務(wù)系統(tǒng)接口,可串行或并行調(diào)用。比如在做創(chuàng)建回收單業(yè)務(wù)時(shí),需要讀取用戶信息,讀取渠道信息,還有相關(guān)的配置信息。我們通過提前查看調(diào)用具體接口的大概耗時(shí),預(yù)估到了串行調(diào)用這些接口會(huì)有超時(shí)的風(fēng)險(xiǎn),因此在讀取這些配置信息時(shí),我們采用異步調(diào)用,減少創(chuàng)建回收單業(yè)務(wù)接口的耗時(shí),保證接口不會(huì)超時(shí)。
3.4.2 監(jiān)控遠(yuǎn)程調(diào)用QPS
圖片
在遠(yuǎn)程調(diào)用中通常用限流防業(yè)務(wù)系統(tǒng)因過多調(diào)用崩潰。但是若都是正常流量,則應(yīng)考慮增機(jī)、調(diào)整限流規(guī)則確保其他業(yè)務(wù)系統(tǒng)穩(wěn)定。所以這時(shí)監(jiān)控的作用就體現(xiàn)出來了,當(dāng)QPS達(dá)到了限流的百分之八十,發(fā)送一個(gè)告警,及時(shí)通知技術(shù)去觀察判斷是不是有別的業(yè)務(wù)系統(tǒng),因?yàn)闃I(yè)務(wù)突增,導(dǎo)致調(diào)用增加,進(jìn)而及時(shí)調(diào)整限流規(guī)則,來滿足別的業(yè)務(wù)系統(tǒng)的調(diào)用。
3.5 監(jiān)控其它基礎(chǔ)依賴指標(biāo)保證系統(tǒng)的穩(wěn)定性
3.5.1 監(jiān)控FGC次數(shù)
圖片
通過監(jiān)控FGC次數(shù),如果頻繁發(fā)生FGC,說明系統(tǒng)現(xiàn)在處于不正常的狀態(tài):1.有可能存在內(nèi)存泄露。2.有可能JVM內(nèi)存配置的過小,不滿足業(yè)務(wù)系統(tǒng)需要。通過這方面的監(jiān)控及時(shí)排查FGC頻繁發(fā)生的原因,減少FGC發(fā)生的次數(shù)也可以提升系統(tǒng)的穩(wěn)定性。
3.5.2 監(jiān)控?cái)?shù)據(jù)庫連接池
圖片
通過監(jiān)控?cái)?shù)據(jù)庫連接池相關(guān)的指標(biāo):
- 通過觀察事務(wù)提交耗時(shí)指標(biāo),可以清晰的觀察到是否存在大量打大事務(wù),影響數(shù)據(jù)庫連接池的連接和釋放。
 - 通過觀察事務(wù)回滾次數(shù)指標(biāo),可以判斷系統(tǒng)中是否存在大量的業(yè)務(wù)異常,導(dǎo)致事務(wù)回滾。
 - 通過觀察事務(wù)提交次數(shù),可以為連接池配置連接數(shù)量提供一定的依賴數(shù)據(jù)。
 
3.5.3 監(jiān)控容器指標(biāo)
圖片
通過監(jiān)控容器相關(guān)指標(biāo)可以防止業(yè)務(wù)系統(tǒng)因?yàn)榛A(chǔ)系統(tǒng)原因?qū)е虏环€(wěn)定。
例如監(jiān)控宿主機(jī)磁盤容量指標(biāo)可以防止因磁盤不足,導(dǎo)致業(yè)務(wù)系統(tǒng)無法讀寫磁盤,比如日志無法寫入等問題。
4 總結(jié)
圖片
轉(zhuǎn)轉(zhuǎn)除了上面的一些舉例還有很多方向的監(jiān)控:虛擬機(jī)指標(biāo)監(jiān)控、線程池監(jiān)控、MQ監(jiān)控、Codis連接池監(jiān)控等等。
因?yàn)闃I(yè)務(wù)系統(tǒng)最終穩(wěn)定性就是靠異常監(jiān)控與及時(shí)預(yù)警來保證的,所以建立完善的監(jiān)控系統(tǒng)和及時(shí)預(yù)警是非常重要的。
提前預(yù)知和識(shí)別問題
- 監(jiān)控和告警系統(tǒng)可以幫助我們實(shí)時(shí)獲取系統(tǒng)的運(yùn)行數(shù)據(jù)和指標(biāo)。
 - 通過對(duì)關(guān)鍵指標(biāo)的監(jiān)控和分析,可以提前預(yù)知系統(tǒng)可能出現(xiàn)的問題,如性能下降、異常錯(cuò)誤、服務(wù)不可用等。
 - 通過告警及時(shí)發(fā)現(xiàn)問題,可以提高問題識(shí)別的速度和準(zhǔn)確性,便于及時(shí)采取相應(yīng)的措施來修復(fù)問題。
 
提高故障響應(yīng)和處理效率
- 及時(shí)發(fā)現(xiàn)和處理故障可以減少系統(tǒng)的停機(jī)時(shí)間,避免影響用戶體驗(yàn)和業(yè)務(wù)運(yùn)行。
 - 配置監(jiān)控和告警系統(tǒng)可以幫助運(yùn)維團(tuán)隊(duì)更快速地響應(yīng)和解決問題,減少故障的恢復(fù)時(shí)間,減少業(yè)務(wù)損失。
 
優(yōu)化系統(tǒng)性能和資源利用
- 監(jiān)控和告警系統(tǒng)可以實(shí)時(shí)監(jiān)測(cè)系統(tǒng)的性能和資源利用情況,如CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)等。
 - 通過對(duì)系統(tǒng)的性能指標(biāo)進(jìn)行監(jiān)控和分析,可以幫助我們了解系統(tǒng)的負(fù)載情況和瓶頸。
 - 及時(shí)進(jìn)行性能優(yōu)化和資源擴(kuò)展,以提高系統(tǒng)的穩(wěn)定性和可擴(kuò)展性。
 
安全風(fēng)險(xiǎn)的監(jiān)測(cè)和應(yīng)對(duì)
- 監(jiān)控和告警系統(tǒng)還可以對(duì)系統(tǒng)的安全風(fēng)險(xiǎn)進(jìn)行實(shí)時(shí)監(jiān)測(cè)和預(yù)警。通過對(duì)異常訪問、漏洞攻擊、異常登錄等進(jìn)行監(jiān)控和分析
 - 可以幫助及時(shí)發(fā)現(xiàn)和應(yīng)對(duì)潛在的安全風(fēng)險(xiǎn),并保護(hù)系統(tǒng)和數(shù)據(jù)的安全。
 
關(guān)于作者
黃敬乾 俠客匯JAVA開發(fā)工程師















 
 
 








 
 
 
 