全局異常捕獲導(dǎo)致Micrometer錯(cuò)誤數(shù)丟失,prometheus+grafana錯(cuò)誤速率no data

描述,當(dāng)我們的prometheus+micrometer來(lái)實(shí)現(xiàn)服務(wù)監(jiān)控時(shí),導(dǎo)致服務(wù)的錯(cuò)誤無(wú)法統(tǒng)計(jì),micrometer作為一個(gè)插件,無(wú)非是基于aop或者攔截器來(lái)統(tǒng)計(jì)jvm的信息和請(qǐng)求,響應(yīng)等,請(qǐng)求的響應(yīng)狀態(tài)來(lái)標(biāo)識(shí)請(qǐng)求的成功與否。當(dāng)我們對(duì)異常進(jìn)行捕獲時(shí),響應(yīng)的response的狀態(tài)就是200,故而基于springboot-actuator的請(qǐng)求失敗就會(huì)被當(dāng)成成功,失敗的請(qǐng)求數(shù)據(jù)就會(huì)變成 no data

下面問(wèn)題處理方案如下:

微服務(wù)中全局異常捕獲導(dǎo)致Micrometer錯(cuò)誤數(shù)丟失,Prometheus+grafana錯(cuò)誤速率no data


原因分析,若是去掉全局異常是可以的,錯(cuò)誤數(shù)量都是ok的,但是因?yàn)檫@個(gè)就可以不要全局異常嗎?當(dāng)然不是,

分析原因:點(diǎn)開(kāi)錯(cuò)誤數(shù)的edit




這里統(tǒng)計(jì)的是:http_server_requests_seconds_count的計(jì)數(shù)器對(duì)象,status = 500或者 status = 501 或者status = 502(以 5 開(kāi)頭的請(qǐng)求結(jié)果)

下面有兩種解決方案:

1:也是最簡(jiǎn)單的,就是可以在你的全局異常捕獲中,設(shè)置HttpServletResponse的 response.setStatus(500) 就可以了 符合你統(tǒng)計(jì)的參數(shù)對(duì)象,和status

2:這個(gè)方案稍微復(fù)雜點(diǎn),但是可以明了 grafana面板的配置屬性和Micrometer的原理,我也是用這種方式,并且不會(huì)影響全局異常捕獲的HttpServletResponse的結(jié)果和狀態(tài)

我這里用的是下面這個(gè)json配置面板 【SLS JVM監(jiān)控大盤(pán)】

面板配置片段如下:

{
  "panels": [
      "targets": [
        {
     //這個(gè)是統(tǒng)計(jì)的表達(dá)式,統(tǒng)計(jì)的http_server_requests_seconds_count計(jì)數(shù)器對(duì)象的status = 5..的速率
          "expr": "sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\", status=~\"5..\"}[1m]))",
          "format": "time_series",
          "intervalFactor": 1,
          "legendFormat": "HTTP - 5xx",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "錯(cuò)誤數(shù)(1分鐘平均)",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      }
    },
    
}

所以可以得到一個(gè)技術(shù)解決方案,那就是我們是不是可以自定義Conuter對(duì)象一個(gè),目測(cè)可行,原理是從一個(gè)http_server_requests_seconds_count對(duì)象中統(tǒng)計(jì)status = 5..的請(qǐng)求次數(shù)

我可以自定義一個(gè)名字 = requests_error_total的 Counter,來(lái)存儲(chǔ)請(qǐng)求異常的次數(shù),然后,修改可視化面板的配置,http_server_requests_seconds_count改成 requests_error_total

在上篇的 prometheus + grafana + nacos 對(duì)微服務(wù)監(jiān)控的文章中的自定義 wlc-prometheus-starter 中 新增一個(gè)bean



這里是定義一個(gè) Counter ,name = requests_error_total的 status = 500 這樣一個(gè)計(jì)數(shù)器作為異常的計(jì)數(shù)器,然后在任何需要增加的異常技術(shù)的地方調(diào)用

 @Autowired
    private Counter exCounter ; // 注入異常的計(jì)數(shù)器

  public Long nextId(){
        exCounter.increment(); //  異常的計(jì)數(shù)器數(shù)量 + 1
        return idGeneratorService.nextId();
    }
這里只是一個(gè)演示,當(dāng)然,如果你的微服務(wù)中全局異常捕獲導(dǎo)致異常數(shù)量沒(méi)統(tǒng)計(jì),可以在全局異常捕獲中 調(diào)用 exCounter.increment();即可



這樣的話每次異常就會(huì)在 name = requests_error_total的 status = 500  的 計(jì)數(shù)器中 進(jìn)行 + 1;

剩下的,就是在面板中展示和計(jì)數(shù)器統(tǒng)計(jì)結(jié)果即可

面板修改








修改前的面板



修改后:





保存后,在grafana重新 import 面板配置即可,也可以覆蓋掉原來(lái)的面板配置






這樣每次異常時(shí),即你調(diào)用 exCounter.increment();時(shí),錯(cuò)誤數(shù)字就會(huì)顯示出來(lái)





看下這個(gè)異常數(shù)的配置的表達(dá)式




這樣就可以實(shí)現(xiàn),在哪里調(diào)用 這個(gè)異常計(jì)數(shù)器。異常計(jì)數(shù)器的數(shù)量就會(huì) + 1,grafana的配置修改后的面板上就會(huì)顯示出來(lái)

需要面板配置的json文件,加老王微信,或者關(guān)注微信公眾號(hào)【IT學(xué)習(xí)道場(chǎng)】在微信公眾號(hào)中給老王回復(fù),老王看到就會(huì)給你發(fā)過(guò)去這個(gè)配置文件哦

大功告成!





作者:IT學(xué)習(xí)道場(chǎng)

歡迎關(guān)注微信公眾號(hào) : IT學(xué)習(xí)道場(chǎng)