当前位置: 首页 > 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相关的指标。

相关文章:

聊聊springboot的TomcatMetricsBinder

序 本文主要研究一下springboot的TomcatMetricsBinder TomcatMetricsAutoConfiguration org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java Configuration(proxyBeanMethods false) ConditionalOnWebApplication C…...

《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码

在注意力机制中&#xff0c;每个查询都会关注所有的键&#xff0d;值对并生成一个注意力输出。由于查询、键和值来自同一组输入&#xff0c;因此被称为 自注意力&#xff08;self-attention&#xff09;&#xff0c;也被称为内部注意力&#xff08;intra-attention&#xff09;…...

2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题 实现代码

根据之前发布的思路 第一步 进行数据合并 import pandas as pd# 读取所有附件的数据 data1 pd.read_excel(附件一.xlsx) data2 pd.read_excel(附件二.xlsx) data3 pd.read_excel(附件三.xlsx) data4 pd.read_excel(附件四.xlsx)# 根据商品编码将附件一和附件二连接 combi…...

larvel 中的api.php_Laravel 开发 API

Laravel10中提示了Target *classController does not exist&#xff0c;为什么呢&#xff1f; 原因是&#xff1a;laravel8开始写法变了。换成了新的写法了 解决方法一&#xff1a; 在路由数组加入App\Http\Controllers\即可。 <?phpuse Illuminate\Support\Facades\Route;…...

虚拟机构建部署单体项目及前后端分离项目

目录 一.部署单体项目 1.远程数据库 1.1远程连接数据库 1.2 新建数据库运行sql文件 2.部署项目到服务器中 3.启动服务器运行 二.部署前后端分离项目 1.远程数据库和部署到服务器 2.利用node环境启动前端项目 3.解决主机无法解析服务器localhost问题 方法一 ​编辑 方法二 一.部…...

C++之特殊类的设计

目录 一、单例模式 1、设计模式 2、单例模式 1、饿汉模式 2、懒汉模式 3、单例对象的释放问题 二、设计一个不能被拷贝的类 三、设计一个只能在堆上创建对象的类 四、设计一个只能在栈上创建对象的类 五、设计一个不能被继承的类 一、单例模式 1、设计模式 概念&am…...

Java练习题2020 -1

统计1到N的整数中&#xff0c;被A除余A-1的偶数的个数 输入说明&#xff1a;整数 N(N<10000), A, (A 输出说明&#xff1a;符合条件的数的个数 输入样例&#xff1a;10 3 输出样例&#xff1a;2 (说明&#xff1a;样例中符合条件的2个数是 2、8) import java.util.Scanner;p…...

LuaTable转C#的列表List和字典Dictionary

LuaTable转C#的列表List和字典Dictionaty 介绍lua中创建表测试lua中list表表转成List表转成Dictionary 键值对表表转成Dictionary 多类型键值对表表转成Dictionary 总结 介绍 之前基本都是从C#中的List或者Dictionary转成luaTable&#xff0c;很少会把LuaTable转成C#的List或者…...

Redis快速上手篇七(集群)

在赶工了..... Redis集群 主从复制的场景无法吗满足主机单点故障时需要引入集群配置 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服务器主要用来处理写请求&#xff0c;部署多台从…...

Mac 安装nvm

安装方案&#xff1a; 1. 从github下载nvm仓库到 ~/目录 地址&#xff1a;https://github.com/nvm-sh/nvm.git git clone https://github.com/nvm-sh/nvm.git 2. 进入nvm目录中执行install.sh等待执行完成&#xff0c;执行的操作方法就是直接将文件拖入到终端然后回车。 3.…...

python 从mssql取出datetime2类型之后格式化

我mssql是datetime2类型&#xff0c;用df取出之后发现是个纳秒的int&#xff08;1698419713000000000 这种&#xff09; 所以格式化的话就需要变成秒为单位&#xff0c;他们之间是10的9次方倍。所以先除以1e9之后用datetime.datetime.fromtimestamp()转换之后再format就行了 l…...

18.2 使用NPCAP库抓取数据包

NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库。它是WinPcap库的一个分支&#xff0c;由Nmap开发团队开发&#xff0c;并在Nmap软件中使用。与WinPcap一样&#xff0c;NPCAP库提供了一些API&#xff0c;使开发人员可以轻松地在其应用程序中捕获和处理网络数据…...

pytest-yaml 测试平台-3.创建执行任务定时执行用例

前言 当项目用例编写完成后&#xff0c;需设置执行策略&#xff0c;可以用到定时任务设置每天几点执行。或者间隔几个小时执行一次。 创建定时任务 创建任务 勾选需要执行的项目以及运行环境 触发器可以支持2种方式&#xff1a;interval 间隔多久触发和 cron 表达式定时执行…...

安卓文件资源中,一个字串包含引用其他字串的写法

具体范例&#xff1a; <string name"product_name" translatable"false">Miscope</string><string name"app_name">string/product_name for USB Camera</string> 注意要先定义再引用。...

解决:谷歌浏览器访问http时,自动转https访问的问题

问题背景&#xff1a;某个系统网站&#xff0c;之前一直用https域名访问&#xff0c;现在改成http域名后&#xff0c;用http访问&#xff0c;谷歌浏览器会自动跳转到https。 解决方法&#xff1a; 在浏览器中输入网址&#xff1a;chrome://net-internals/#hsts -》 在“Delete…...

MQTT协议和边缘计算

1.基本概念 MQTT是基于TCP/IP协议栈构建的异步通信消息协议&#xff0c;是一种轻量级的发布、订阅信息传输协议。可以在不可靠的网络环境中进行扩展&#xff0c;适用于设备硬件存储空间或网络带宽有限的场景。使用MQTT协议&#xff0c;消息发送者与接收者不受时间和空间的限制…...

Redis(04)| 数据结构-压缩列表

压缩列表的最大特点&#xff0c;就是它被设计成一种内存紧凑型的数据结构&#xff0c;占用一块连续的内存空间&#xff0c;不仅可以利用 CPU 缓存&#xff0c;而且会针对不同长度的数据&#xff0c;进行相应编码&#xff0c;这种方法可以有效地节省内存开销。 但是&#xff0c;…...

516 最长回文子序列(区间DP)(灵神笔记)

题目 最长回文子序列 给你一个字符串 s &#xff0c;找出其中最长的回文子序列&#xff0c;并返回该序列的长度。 子序列定义为&#xff1a;不改变剩余字符顺序的情况下&#xff0c;删除某些字符或者不删除任何字符形成的一个序列。 示例 1&#xff1a; 输入&#xff1a;s …...

Kafka - 异步/同步发送API

文章目录 异步发送普通异步发送异步发送流程Code 带回调函数的异步发送带回调函数的异步发送流程Code 同步发送API 异步发送 普通异步发送 需求&#xff1a;创建Kafka生产者&#xff0c;采用异步的方式发送到Kafka broker 异步发送流程 Code <!-- https://mvnrepository…...

嵌套for循环在外层循环和内层循环中使用两个Executors.newCachedThreadPool缓存线程池执行操作

1. 首先&#xff0c;我们需要创建两个ExecutorService对象&#xff0c;这两个对象将作为我们的缓存线程池。 2. 然后&#xff0c;我们使用嵌套的for循环来执行我们的操作。在每个外层循环中&#xff0c;我们将创建一个新的任务并提交给外层线程池。在这个任务中&#xff0c;我…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...