当前位置: 首页 > news >正文

聊聊springboot的TomcatMetricsBinder

本文主要研究一下springboot的TomcatMetricsBinder

TomcatMetricsAutoConfiguration

org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({ TomcatMetrics.class, Manager.class })
@AutoConfigureAfter(CompositeMeterRegistryAutoConfiguration.class)
public class TomcatMetricsAutoConfiguration {@Bean@ConditionalOnBean(MeterRegistry.class)@ConditionalOnMissingBean({ TomcatMetrics.class, TomcatMetricsBinder.class })public TomcatMetricsBinder tomcatMetricsBinder(MeterRegistry meterRegistry) {return new TomcatMetricsBinder(meterRegistry);}}

TomcatMetricsAutoConfiguration在CompositeMeterRegistryAutoConfiguration之后自动配置,它会创建TomcatMetricsBinder

TomcatMetricsBinder

org/springframework/boot/actuate/metrics/web/tomcat/TomcatMetricsBinder.java

public class TomcatMetricsBinder implements ApplicationListener<ApplicationStartedEvent>, DisposableBean {private final MeterRegistry meterRegistry;private final Iterable<Tag> tags;private volatile TomcatMetrics tomcatMetrics;public TomcatMetricsBinder(MeterRegistry meterRegistry) {this(meterRegistry, Collections.emptyList());}public TomcatMetricsBinder(MeterRegistry meterRegistry, Iterable<Tag> tags) {this.meterRegistry = meterRegistry;this.tags = tags;}@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {ApplicationContext applicationContext = event.getApplicationContext();Manager manager = findManager(applicationContext);this.tomcatMetrics = new TomcatMetrics(manager, this.tags);this.tomcatMetrics.bindTo(this.meterRegistry);}private Manager findManager(ApplicationContext applicationContext) {if (applicationContext instanceof WebServerApplicationContext) {WebServer webServer = ((WebServerApplicationContext) applicationContext).getWebServer();if (webServer instanceof TomcatWebServer) {Context context = findContext((TomcatWebServer) webServer);return context.getManager();}}return null;}private Context findContext(TomcatWebServer tomcatWebServer) {for (Container container : tomcatWebServer.getTomcat().getHost().findChildren()) {if (container instanceof Context) {return (Context) container;}}return null;}@Overridepublic void destroy() {if (this.tomcatMetrics != null) {this.tomcatMetrics.close();}}}

TomcatMetricsBinder实现了ApplicationListener监听ApplicationStartedEvent,同时也实现了DisposableBean接口;其onApplicationEvent方法会获取applicationContext再获取tomcat的Manager,最后创建tomcatMetrics,然后执行bindTo方法;其close方法主要是执行tomcatMetrics的close方法

TomcatMetrics

io/micrometer/core/instrument/binder/tomcat/TomcatMetrics.java

@NonNullApi
@NonNullFields
public class TomcatMetrics implements MeterBinder {private static final String JMX_DOMAIN_EMBEDDED = "Tomcat";private static final String JMX_DOMAIN_STANDALONE = "Catalina";private static final String OBJECT_NAME_SERVER_SUFFIX = ":type=Server";private static final String OBJECT_NAME_SERVER_EMBEDDED = JMX_DOMAIN_EMBEDDED + OBJECT_NAME_SERVER_SUFFIX;private static final String OBJECT_NAME_SERVER_STANDALONE = JMX_DOMAIN_STANDALONE + OBJECT_NAME_SERVER_SUFFIX;@Nullableprivate final Manager manager;private final MBeanServer mBeanServer;private final Iterable<Tag> tags;private volatile String jmxDomain;@Overridepublic void bindTo(MeterRegistry registry) {registerGlobalRequestMetrics(registry);registerServletMetrics(registry);registerCacheMetrics(registry);registerThreadPoolMetrics(registry);registerSessionMetrics(registry);}//......
}            

TomcatMetrics实现了MeterBinder接口,其bindTo方法主要是执行了registerGlobalRequestMetrics、registerServletMetrics、registerCacheMetrics、registerThreadPoolMetrics、registerSessionMetrics

registerGlobalRequestMetrics

    private void registerGlobalRequestMetrics(MeterRegistry registry) {registerMetricsEventually("type", "GlobalRequestProcessor", (name, allTags) -> {FunctionCounter.builder("tomcat.global.sent", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "bytesSent"))).tags(allTags).baseUnit(BaseUnits.BYTES).register(registry);FunctionCounter.builder("tomcat.global.received", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "bytesReceived"))).tags(allTags).baseUnit(BaseUnits.BYTES).register(registry);FunctionCounter.builder("tomcat.global.error", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "errorCount"))).tags(allTags).register(registry);FunctionTimer.builder("tomcat.global.request", mBeanServer,s -> safeLong(() -> s.getAttribute(name, "requestCount")),s -> safeDouble(() -> s.getAttribute(name, "processingTime")), TimeUnit.MILLISECONDS).tags(allTags).register(registry);TimeGauge.builder("tomcat.global.request.max", mBeanServer, TimeUnit.MILLISECONDS,s -> safeDouble(() -> s.getAttribute(name, "maxTime"))).tags(allTags).register(registry);});}    

registerGlobalRequestMetrics主要是注册了请求相关的指标

registerServletMetrics

    private void registerServletMetrics(MeterRegistry registry) {registerMetricsEventually("j2eeType", "Servlet", (name, allTags) -> {FunctionCounter.builder("tomcat.servlet.error", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "errorCount"))).tags(allTags).register(registry);FunctionTimer.builder("tomcat.servlet.request", mBeanServer,s -> safeLong(() -> s.getAttribute(name, "requestCount")),s -> safeDouble(() -> s.getAttribute(name, "processingTime")), TimeUnit.MILLISECONDS).tags(allTags).register(registry);TimeGauge.builder("tomcat.servlet.request.max", mBeanServer, TimeUnit.MILLISECONDS,s -> safeDouble(() -> s.getAttribute(name, "maxTime"))).tags(allTags).register(registry);});}

registerServletMetrics主要是注册了servlet相关的errorCount、requestCount及maxTime

registerCacheMetrics

    private void registerCacheMetrics(MeterRegistry registry) {registerMetricsEventually("type", "StringCache", (name, allTags) -> {FunctionCounter.builder("tomcat.cache.access", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "accessCount"))).tags(allTags).register(registry);FunctionCounter.builder("tomcat.cache.hit", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "hitCount"))).tags(allTags).register(registry);});}

registerCacheMetrics主要是注册了tomcat内部cache的accessCount、hitCount

registerThreadPoolMetrics

    private void registerThreadPoolMetrics(MeterRegistry registry) {registerMetricsEventually("type", "ThreadPool", (name, allTags) -> {Gauge.builder("tomcat.threads.config.max", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "maxThreads"))).tags(allTags).baseUnit(BaseUnits.THREADS).register(registry);Gauge.builder("tomcat.threads.busy", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "currentThreadsBusy"))).tags(allTags).baseUnit(BaseUnits.THREADS).register(registry);Gauge.builder("tomcat.threads.current", mBeanServer,s -> safeDouble(() -> s.getAttribute(name, "currentThreadCount"))).tags(allTags).baseUnit(BaseUnits.THREADS).register(registry);});}

registerThreadPoolMetrics主要是注册了tomcat线程池的相关指标

registerSessionMetrics

    private void registerSessionMetrics(MeterRegistry registry) {if (manager == null) {// If the binder is created but unable to find the session manager don't register those metricsreturn;}Gauge.builder("tomcat.sessions.active.max", manager, Manager::getMaxActive).tags(tags).baseUnit("sessions").register(registry);Gauge.builder("tomcat.sessions.active.current", manager, Manager::getActiveSessions).tags(tags).baseUnit("sessions").register(registry);FunctionCounter.builder("tomcat.sessions.created", manager, Manager::getSessionCounter).tags(tags).baseUnit("sessions").register(registry);FunctionCounter.builder("tomcat.sessions.expired", manager, Manager::getExpiredSessions).tags(tags).baseUnit("sessions").register(registry);FunctionCounter.builder("tomcat.sessions.rejected", manager, Manager::getRejectedSessions).tags(tags).baseUnit("sessions").register(registry);TimeGauge.builder("tomcat.sessions.alive.max", manager, TimeUnit.SECONDS, Manager::getSessionMaxAliveTime).tags(tags).register(registry);}

registerSessionMetrics主要是注册了tomcat的session相关指标

小结

springboot的TomcatMetricsBinder主要是接收ApplicationStartedEvent然后创建TomcatMetrics执行bindTo进行注册,TomcatMetrics主要注册了globalRequest、servlet、cache、threadPool、session相关的指标。

http://www.lryc.cn/news/208913.html

相关文章:

  • 《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码
  • 2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题 实现代码
  • larvel 中的api.php_Laravel 开发 API
  • 虚拟机构建部署单体项目及前后端分离项目
  • C++之特殊类的设计
  • Java练习题2020 -1
  • LuaTable转C#的列表List和字典Dictionary
  • Redis快速上手篇七(集群)
  • Mac 安装nvm
  • python 从mssql取出datetime2类型之后格式化
  • 18.2 使用NPCAP库抓取数据包
  • pytest-yaml 测试平台-3.创建执行任务定时执行用例
  • 安卓文件资源中,一个字串包含引用其他字串的写法
  • 解决:谷歌浏览器访问http时,自动转https访问的问题
  • MQTT协议和边缘计算
  • Redis(04)| 数据结构-压缩列表
  • 516 最长回文子序列(区间DP)(灵神笔记)
  • Kafka - 异步/同步发送API
  • 嵌套for循环在外层循环和内层循环中使用两个Executors.newCachedThreadPool缓存线程池执行操作
  • 【uniapp+云函数调用】人脸识别,实人认证,适用于app,具体思路解析,已实现
  • 系列十六、bean有哪些生命周期的回调方法?有哪几种实现方式?
  • 2023平台工程崭露头角,AI 带来新机遇与挑战
  • 如何使用python快速修改Excel表单中的大量数据
  • ✔ ★【备战实习(面经+项目+算法)】 10.27学习
  • 视频分辨率/帧率/码率选择参考
  • LeetCode75——Day18
  • Java NIO 高并发开发
  • 8.循环神经网络
  • [C++随想录] map和set的使用
  • 公网IP怎么设置?公网ip有哪些优点和缺点?