全局异常捕获导致Micrometer错误数丢失
作者 | IT学习道场
来源 | IT学习道场(ID:itlearndojo)
描述,当我们的prometheus+micrometer来实现服务监控时,导致服务的错误无法统计,micrometer作为一个插件,无非是基于aop或者拦截器来统计jvm的信息和请求,响应等,请求的响应状态来标识请求的成功与否。当我们对异常进行捕获时,响应的response的状态就是200,故而基于springboot-actuator的请求失败就会被当成成功,失败的请求数据就会变成 no data
下面问题处理方案如下:
微服务中全局异常捕获导致Micrometer错误数丢失,Prometheus+grafana错误速率no data

原因分析,若是去掉全局异常是可以的,错误数量都是ok的,但是因为这个就可以不要全局异常吗?当然不是,
分析原因:点开错误数的edit


这里统计的是:http_server_requests_seconds_count的计数器对象,status = 500或者 status = 501 或者status = 502(以 5 开头的请求结果)
下面有两种解决方案:
1:也是最简单的,就是可以在你的全局异常捕获中,设置HttpServletResponse的 response.setStatus(500) 就可以了 符合你统计的参数对象,和status
2:这个方案稍微复杂点,但是可以明了 grafana面板的配置属性和Micrometer的原理,我也是用这种方式,并且不会影响全局异常捕获的HttpServletResponse的结果和状态
我这里用的是下面这个json配置面板 【SLS JVM监控大盘】
面板配置片段如下:
{
  "panels": [
      "targets": [
        {
     //这个是统计的表达式,统计的http_server_requests_seconds_count计数器对象的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": "错误数(1分钟平均)",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      }
    },
    
}
所以可以得到一个技术解决方案,那就是我们是不是可以自定义Conuter对象一个,目测可行,原理是从一个http_server_requests_seconds_count对象中统计status = 5..的请求次数
我可以自定义一个名字 = requests_error_total的 Counter,来存储请求异常的次数,然后,修改可视化面板的配置,http_server_requests_seconds_count改成 requests_error_total
在上篇的 prometheus + grafana + nacos 对微服务监控的文章中的自定义 wlc-prometheus-starter 中 新增一个bean

这里是定义一个 Counter ,name = requests_error_total的 status = 500 这样一个计数器作为异常的计数器,然后在任何需要增加的异常技术的地方调用
 @Autowired
    private Counter exCounter ; // 注入异常的计数器
  public Long nextId(){
        exCounter.increment(); //  异常的计数器数量 + 1
        return idGeneratorService.nextId();
    }
这里只是一个演示,当然,如果你的微服务中全局异常捕获导致异常数量没统计,可以在全局异常捕获中 调用 exCounter.increment();即可

这样的话每次异常就会在 name = requests_error_total的 status = 500 的 计数器中 进行 + 1;
剩下的,就是在面板中展示和计数器统计结果即可
面板修改

修改前的面板

修改后:

保存后,在grafana重新 import 面板配置即可,也可以覆盖掉原来的面板配置


这样每次异常时,即你调用 exCounter.increment();时,错误数字就会显示出来


看下这个异常数的配置的表达式

这样就可以实现,在哪里调用 这个异常计数器。异常计数器的数量就会 + 1,grafana的配置修改后的面板上就会显示出来
需要面板配置的json文件,加老王微信,或者关注微信公众号【IT学习道场】在微信公众号中给老王回复,老王看到就会给你发过去这个配置文件哦
大功告成!




















