前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot+Prometheus:微服务开发中自定义业务监控指标的几点经验

SpringBoot+Prometheus:微服务开发中自定义业务监控指标的几点经验

作者头像
王录华
修改2019-08-08 17:53:38
15K0
修改2019-08-08 17:53:38
举报
文章被收录于专栏:云服务与SRE架构师社区

作者:橙色马路

马楠的上一篇文章中,我们已经了解到Prometheus的一大优势,是可以在应用内定义自己的指标做监控。我们在 SpringBoot 做微服务的生产环境中,使用自定义指标监控诸多物联网传感器,时序数据结构简单清晰,监控与统计反应迅捷,效果良好。

SpringBoot 2的actuator中默认使用Micrometer作为指标支持库。本身已经内置了许多开箱即用的指标。自定义的指标注册以后,也会被融合在相同的uri(/actuator/prometheus)中统一输出,非常方便。

1. 注册表(Registry)

Prometheus是用定时Pull方式去服务器拉取指标数据,以拉取的时间打点做时间轴,形成时间序列。应用服务器只需暴露当下时刻的指标值即可,所以数据模型本质是一个个KV键值对,存放在全局的容器,Prometheus来获取的时候,将容器内的值格式化输出。此处的容器即为计量注册表(MeterRegistry) 。

几种内置的Registry如下

SimpleMeterRegistry:极简实现,数据存取在内存中,每项数据只保留最新一次的数值。默认SpringBoot会帮你autowire一个。

CompositeMeterRegistry:用组合模式帮你将多个注册表串联成一个对外接口。全局的Metrics.globalRegistry就是这么个组合模式接口

2. 两种常用指标类型(Metric Type)

gauge: 可增可减计数器,反应某值当前一刻状态。比如称重传感器的当前重量,温度传感器的当前温度。

方式一:

代码语言:javascript
复制
Gauge.builder("gn.temperature.gauge", new AtomicInteger(37), AtomicInteger::get)

方式二:

代码语言:javascript
复制
registry.gauge("gn.temperature.gauge", Tags.of("site", "SiteA", "cab", "cab01"), new AtomicInteger(37));

两者等价,会输出成如下指标:

代码语言:javascript
复制
# HELP gn_temperature_gauge_value for cab temperature
# TYPE gn_temperature_gauge_value
gn_temperature_gauge_value{application="xxx",cab="cab01",site="SiteA",} 37.0

注意定义的名称转换:其中"."被换成了"_",gauge类型的指标最后加上了"_value"做结尾。指标命名只能为ASCII字母、数字、下划线和冒号,且必须配正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*

counter:只增不减计数器,是Gauge的一个特例。适用于只有服务器重启时候才会重置的计数场景。比如"用户访问次数",某接口失败次数"等等。API 使用方式类似。

代码语言:javascript
复制
Counter counter = Counter.builder("gn.beat.counter")
  .tags("site", "SiteA", "function", "foo")
  .description("for request errors")
  .register(registry);

counter.increment();

会输出成如下指标:

代码语言:javascript
复制
# HELP gn_beat_counter_total for request errors
# TYPE gn_beat_counter_total counter
gn_beat_counter_total{application="xxx",function="foo",site="SiteA",} 1.0

3. 融入到系统的方式

方式一,业务系统埋点:

代码语言:javascript
复制
@Component
public class SampleBean {
    private final Counter counter;

    public SampleBean(MeterRegistry registry) {
        this.counter = registry.counter("gn.beat.counter");
    }

    public void handleMessage(String message) {
        this.counter.increment();
        // handle message implementation
    }
}

方式二:MeterBinder

SpringBoot中提供了MeterBinder接口用于申明与注册meterRegistry。自定义Metrics只需要实现MeterBinder接口,Spring会自动发现并完成后续的杂活。

代码语言:javascript
复制
@Bean
public class MyMetrics implements MeterBinder {
   @Override
   public void bindTo(MeterRegistry meterRegistry) {
    //此处添加相关指标
    meterRegistry.gauge("gn.temperature.gauge", Tags.of("site", "SiteA", "cab", "cab01"), new AtomicInteger(37));
   }
}

Spring优秀的解耦架构还可以方便地搭配自定义配置项方式使用。

4. 垃圾回收与NaN

指标值注册到registry中默认为弱引用,若函数调用调用周期结束,则该值会被 Java 给标记并 GC 掉。对应的指标输出的值则会很快会变成了NaN。

此种短状态适用于心跳类型的指标,在预警系统中可以及时发现没有按时上报的点。

但对于相对长时间想保持住特定指标值,需要显式给到对应变量强引用。比如使用一个实例化的HashMap来 cache 相关的值。

如上段代码中,方式一为强引用,方式二则弱引用。

5. 指标设计与选型

名称 + {一组tag} + 值 为一指标形式。

如某库位温度指标形式如下:

代码语言:javascript
复制
gn_temperature_gauge_value{application="xxx",cab="cab01",site="SiteA"} 37.0

tag中值为 String 型,尽量选取『可识别』,『有限集合』的值作为 tag,比如主机,柜号,库位等等。每一个tag值都会产生一个维度,不同的 tag值+名称会被记录成不同的时间序列。

某些很有潜力膨胀到"无限量"的值如各种ID、邮件地址、时间戳等,就不适宜选做 tag的值

后期若使用 grafana 绘制特定指标变化图,不同时间序列也会对应到不同的多条曲线。

指标值为 double 型: 对于自定义的数值型,如温度,访问次数等的指标,原样输出即可。

若输入某些状态类的值,可定义成数值型。比如 Prometheus 中的存活状态指标 UP = 1。类似如某后台 Job 状态(pending, running, stopped),可依样定义为10,20,30。

6. 集群部署下多微服务指标汇聚

对于Prometheus这类基于Pull模式的监控平台而言,往往由中心server来决定采集的目标有多少有哪些,所以在微服务在集群模式下,多端Metrics的聚合可通过Prometheus的Pull模式天然汇聚。

通过服务发现形式,获取到当前集群中所有节点的信息,更新配置文件并且重建抓取的列表,将分散的Metrics聚合到中心服务器。

Prometheus本身支持 DNS, Consul, Kubernetes, OpenStack, EC2 等发现机制。在Kubernetes下,可通过与Kubernetes API集成目前主要支持多服务发现模式,如Node、Service、Pod、Endpoints、Ingress等。

部署架构的示意图如下:

这部分由部署层实现,对应用层透明。

7. 关于作者

橙色马路:创业者,技术管理与架构,ex-Oracler。

相关参考:

https://micrometer.io/docs/concepts

https://spring.io/blog/2018/03/16/micrometer-spring-boot-2-s-new-application-metrics-collector

https://winderresearch.com/introduction-to-monitoring-microservices-with-prometheus/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云服务与SRE架构师社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4. 垃圾回收与NaN
  • 5. 指标设计与选型
  • 6. 集群部署下多微服务指标汇聚
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档