Tomcat 编程式启动 JMX 监控

news/2024/11/16 11:59:26/

通过这篇文章,我们可以了解到,利用 JMX 技术可以方便获取 Tomcat 监控情况。但是我们采用自研的框架而非大家常见的 SpringBoot,于是就不能方便地通过设置配置开启 Tomcat 的 JMX,——尽管我们也是基于 Tomcat 的 Web 容器,而是还是 SpringMVC。

在笔者一番尝试下,终于实现了“Enable Embedded Tomcat JMX Programmatically”,所谓 Programmatically 就是编程式的用 Java 代码去配置。实际情况也很简单,就是在 Tomcat 启动的LifecycleEvent事件中加入:

context.addLifecycleListener((LifecycleEvent event) -> {if (isStatedSpring || (event.getLifecycle().getState() != LifecycleState.STARTING_PREP))return;BaseWebInitializer.coreStartup(context.getServletContext(), clz);
//			anotherWayToStartStrping();if (isEnableJMX) {try {LocateRegistry.createRegistry(9011);JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:9011/jmxrmi"),null,ManagementFactory.getPlatformMBeanServer());cs.start();LOGGER.info("成功启动 JMXConnectorServer");} catch (IOException e) {e.printStackTrace();}}isStatedSpring = true;springTime = System.currentTimeMillis() - startedTime;});

要注意的是端口的配置,当前是 9011。

另外如果要鉴权,把newJMXConnectorServer()的第二个参数environmentnull改为一个 map。

哦,对了,还有 Maven 的依赖,——貌似 8 最高的也就这个版本。

<!-- 监控用 -->
<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-catalina-jmx-remote</artifactId><version>8.5.75</version><type>jar</type>
</dependency>

连接 JMX

刚才的配置就像一个服务端,而接着我们这一步就相当于是客户端的连接。先准备好连接地址:

String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:9011/jmxrmi";// 如果要鉴权,还要配置下面的,传入到 environment
Map<String, String[]> map = new HashMap<>();
String[] credentials = new String[]{"monitorRole", "tomcat"};
map.put("jmx.remote.credentials", credentials);

进行连接:

MBeanServerConnection msc = JMXConnectorFactory.connect(new JMXServiceURL(jmxURL)).getMBeanServerConnection();

分门别类地查询

成功连接后,会返回大量的信息。JMX 提供了一种 Domain 命名空间的概念,是为第一的大分类。我们可以打印 Domains 出来,再用getObjectNamesByDomain()列出子类 :

for (String domain : msc.getDomains())System.out.println(domain);List<Node> tomcat = MonitorUtils.getObjectNamesByDomain(msc, "Tomcat");

Node 是我们对结果的封装,实际最重要是里面的fullName即对应 JMX API 的CanonicalName,它就是对象名称 ObjectName,以此来获取具体的属性。

ObjectName threadObjName = new ObjectName("Tomcat:name=\"http-nio-8301\",type=ThreadPool");
System.out.println("currentThreadCount:" + msc.getAttribute(threadObjName, "currentThreadCount"));// tomcat的线程数对应的属性值

因为是自定义的 Tomcat,所以 ObjectName 会不一样。常见的 Tomcat 是

ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8301");// 端口最好是动态取得

于是就必须通过前面说的getObjectNamesByDomain()“人肉”查找。另外也要注意 Tomcat 的端口配置。

获取 Tomcat 监控

只要能成功连接并获取 JMX 信息,下一步就是将其转换为监控信息渲染到前端。

参考

  • 《JConsole、VisualVM 依赖的 JMX 技术》

http://www.ppmy.cn/news/1010168.html

相关文章

JAVA实现二分法查找算法

现实生活中经常会遇到将具有某个特征的元素选择出来&#xff0c;并找出对应的位置。 现在来一个小测验&#xff0c;在以数组【1&#xff0c;4&#xff0c;8&#xff0c;3&#xff0c;0&#xff0c;7&#xff0c;56】中找到8所在的位置&#xff0c;很明显大家可以通过直观的感受…

Linux 系统编程 开篇/ 文件的打开/创建

从本节开始学习关于Linux系统编程的知识&#xff01; 学习Linux的系统编程有非常多的知识点&#xff0c;在应用层面&#xff0c;很重要的一点就是学习如何“用代码操作文件来实现文件创建&#xff0c;打开&#xff0c;编辑等自动化执行” 那如何自动化实现对文件的创建&#…

学python的心得体会1000字,学python的心得体会2000字

这篇文章主要介绍了学python的心得体会2000字&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1. 初学者应该从简单的练习开始&#xff0c;先掌握基本的语法和概念&#xff0c;…

【网络基础实战之路】基于三个分公司的内网搭建并连接运营商的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS&#xff1a;本要求基于…

6年资深测试整理,接口测试总结,你不知道的都在这了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试 是测试…

如何将 dubbo filter 拦截器原理运用到日志拦截器中?

业务背景 我们希望可以在使用日志拦截器时&#xff0c;定义属于自己的拦截器方法。 实现的方式有很多种&#xff0c;我们分别来看一下。 拓展阅读 java 注解结合 spring aop 实现自动输出日志 java 注解结合 spring aop 实现日志traceId唯一标识 java 注解结合 spring ao…

Java - 两种判断闰年的方法

&#x1f914;️判断一个年份是否是闰年的常规方法是遵循以下规则&#xff1a; 如果年份能够被4整除&#xff0c;但不能被100整除&#xff0c;那么它是闰年。如果年份能够被400整除&#xff0c;那么它也是闰年。 boolean b1 (y & 3) 0 && ((y % 100 ! 0) || (y %…

Netty:通过Channel发送ByteBuf的数据,只发送可读的字节

说明 使用Netty Channel发送数据的时候&#xff0c;如果发送的数据存放在ByteBuf中&#xff0c;那么只会发送ByteBuf中可读的字节。即便容量&#xff08;capacity&#xff09;大于可读字节数&#xff0c;那也不会多发送数据。 示例 代码片段 package com.thb.power.termina…