阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

集成JMX

269次阅读
没有评论

共计 5425 个字符,预计需要花费 14 分钟才能阅读完成。

在 Spring 中,可以方便地集成 JMX。

那么第一个问题来了:什么是 JMX?

JMX 是 Java Management Extensions,它是一个 Java 平台的管理和监控接口。为什么要搞 JMX 呢?因为在所有的应用程序中,对运行中的程序进行监控都是非常重要的,Java 应用程序也不例外。我们肯定希望知道 Java 应用程序当前的状态,例如,占用了多少内存,分配了多少内存,当前有多少活动线程,有多少休眠线程等等。如何获取这些信息呢?

为了标准化管理和监控,Java 平台使用 JMX 作为管理和监控的标准接口,任何程序,只要按 JMX 规范访问这个接口,就可以获取所有管理与监控信息。

实际上,常用的运维监控如 Zabbix、Nagios 等工具对 JVM 本身的监控都是通过 JMX 获取的信息。

因为 JMX 是一个标准接口,不但可以用于管理 JVM,还可以管理应用程序自身。下图是 JMX 的架构:

    ┌─────────┐  ┌─────────┐
    │jconsole │  │   Web   │
    └─────────┘  └─────────┘
         │            │
┌ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─
 JVM     ▼            ▼        │
│   ┌─────────┐  ┌─────────┐
  ┌─┤Connector├──┤ Adaptor ├─┐ │
│ │ └─────────┘  └─────────┘ │
  │       MBeanServer        │ │
│ │ ┌──────┐┌──────┐┌──────┐ │
  └─┤MBean1├┤MBean2├┤MBean3├─┘ │
│   └──────┘└──────┘└──────┘
 ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

JMX 把所有被管理的资源都称为 MBean(Managed Bean),这些 MBean 全部由 MBeanServer 管理,如果要访问 MBean,可以通过 MBeanServer 对外提供的访问接口,例如通过 RMI 或 HTTP 访问。

注意到使用 JMX 不需要安装任何额外组件,也不需要第三方库,因为 MBeanServer 已经内置在 JavaSE 标准库中了。JavaSE 还提供了一个 jconsole 程序,用于通过 RMI 连接到 MBeanServer,这样就可以管理整个 Java 进程。

除了 JVM 会把自身的各种资源以 MBean 注册到 JMX 中,我们自己的配置、监控信息也可以作为 MBean 注册到 JMX,这样,管理程序就可以直接控制我们暴露的 MBean。因此,应用程序使用 JMX,只需要两步:

  1. 编写 MBean 提供管理接口和监控数据;
  2. 注册 MBean。

在 Spring 应用程序中,使用 JMX 只需要一步:

  1. 编写 MBean 提供管理接口和监控数据。

第二步注册的过程由 Spring 自动完成。我们以实际工程为例,首先在 AppConfig 中加上 @EnableMBeanExport 注解,告诉 Spring 自动注册 MBean:

@Configuration
@ComponentScan
@EnableWebMvc
@EnableMBeanExport // 自动注册 MBean
@EnableTransactionManagement
@PropertySource({"classpath:/jdbc.properties"})
public class AppConfig {...}

剩下的全部工作就是编写 MBean。我们以实际问题为例,假设我们希望给应用程序添加一个 IP 黑名单功能,凡是在黑名单中的 IP 禁止访问,传统的做法是定义一个配置文件,启动的时候读取:

# blacklist.txt
1.2.3.4
5.6.7.8
2.2.3.4
...

如果要修改黑名单怎么办?修改配置文件,然后重启应用程序。

但是每次都重启应用程序实在是太麻烦了,能不能不重启应用程序?可以自己写一个定时读取配置文件的功能,检测到文件改动时自动重新读取。

上述需求本质上是在应用程序运行期间对参数、配置等进行热更新并要求尽快生效。如果以 JMX 的方式实现,我们不必自己编写自动重新读取等任何代码,只需要提供一个符合 JMX 标准的 MBean 来存储配置即可。

还是以 IP 黑名单为例,JMX 的 MBean 通常以 MBean 结尾,因此我们遵循标准命名规范,首先编写一个BlacklistMBean

public class BlacklistMBean {private Set<String> ips = new HashSet<>();

    public String[] getBlacklist() {return ips.toArray(String[]::new);
    }

    public void addBlacklist(String ip) {ips.add(ip);
    }

    public void removeBlacklist(String ip) {ips.remove(ip);
    }

    public boolean shouldBlock(String ip) {return ips.contains(ip);
    }
}

这个 MBean 没什么特殊的,它的逻辑和普通 Java 类没有任何区别。

下一步,我们要使用 JMX 的客户端来实时热更新这个 MBean,所以要给它加上一些注解,让 Spring 能根据注解自动把相关方法注册到 MBeanServer 中:

@Component
@ManagedResource(objectName = "sample:name=blacklist", description = "Blacklist of IP addresses")
public class BlacklistMBean {private Set<String> ips = new HashSet<>();

    @ManagedAttribute(description = "Get IP addresses in blacklist")
    public String[] getBlacklist() {return ips.toArray(String[]::new);
    }

    @ManagedOperation
    @ManagedOperationParameter(name = "ip", description = "Target IP address that will be added to blacklist")
    public void addBlacklist(String ip) {ips.add(ip);
    }

    @ManagedOperation
    @ManagedOperationParameter(name = "ip", description = "Target IP address that will be removed from blacklist")
    public void removeBlacklist(String ip) {ips.remove(ip);
    }

    public boolean shouldBlock(String ip) {return ips.contains(ip);
    }
}

观察上述代码,BlacklistMBean首先是一个标准的 Spring 管理的 Bean,其次,添加了 @ManagedResource 表示这是一个 MBean,将要被注册到 JMX。objectName 指定了这个 MBean 的名字,通常以 company:name=Xxx 来分类 MBean。

对于属性,使用 @ManagedAttribute 注解标注。上述 MBean 只有 get 属性,没有 set 属性,说明这是一个只读属性。

对于操作,使用 @ManagedOperation 注解标准。上述 MBean 定义了两个操作:addBlacklist()removeBlacklist(),其他方法如shouldBlock() 不会被暴露给 JMX。

使用 MBean 和普通 Bean 是完全一样的。例如,我们在 BlacklistInterceptor 对 IP 进行黑名单拦截:

@Order(1)
@Component
public class BlacklistInterceptor implements HandlerInterceptor {final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    BlacklistMBean blacklistMBean;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {String ip = request.getRemoteAddr();
        logger.info("check ip address {}...", ip);
        // 是否在黑名单中:
        if (blacklistMBean.shouldBlock(ip)) {logger.warn("will block ip {} for it is in blacklist.", ip);
            // 发送 403 错误响应:
            response.sendError(403);
            return false;
        }
        return true;
    }
}

下一步就是正常启动 Web 应用程序,不要关闭它,我们打开另一个命令行窗口,输入 jconsole 启动 JavaSE 自带的一个 JMX 客户端程序:

集成 JMX

通过 jconsole 连接到一个 Java 进程最简单的方法是直接在 Local Process 中找到正在运行的AppConfig,点击 Connect 即可连接到我们当前正在运行的 Web 应用,在 jconsole 中可直接看到内存、CPU 等资源的监控。

我们点击 MBean,左侧按分类列出所有 MBean,可以在 java.lang 查看内存等信息:

集成 JMX

细心的童鞋可以看到 HikariCP 连接池也是通过 JMX 监控的。

sample 中可以看到我们自己的 MBean,点击可查看属性blacklist

集成 JMX

点击 OperationsaddBlacklist,可以填入127.0.0.1 并点击 addBlacklist 按钮,相当于 jconsole 通过 JMX 接口,调用了我们自己的 BlacklistMBeanaddBlacklist()方法,传入的参数就是填入的127.0.0.1

集成 JMX

再次查看属性blacklist,可以看到结果已经更新了:

集成 JMX

我们可以在浏览器中测试一下黑名单功能是否已生效:

集成 JMX

可见,127.0.0.1确实被添加到了黑名单,后台日志打印如下:

2020-06-06 20:22:12 INFO  c.i.l.web.BlacklistInterceptor - check ip address 127.0.0.1...
2020-06-06 20:22:12 WARN  c.i.l.web.BlacklistInterceptor - will block ip 127.0.0.1 for it is in blacklist.

注意:如果使用 IPv6,那么需要把 0:0:0:0:0:0:0:1 这个本机地址加到黑名单。

如果从 jconsole 中调用 removeBlacklist 移除127.0.0.1,刷新浏览器可以看到又允许访问了。

使用 jconsole 直接通过 Local Process 连接 JVM 有个限制,就是 jconsole 和正在运行的 JVM 必须在同一台机器。如果要远程连接,首先要打开 JMX 端口。我们在启动 AppConfig 时,需要传入以下 JVM 启动参数:

  • -Dcom.sun.management.jmxremote.port=19999
  • -Dcom.sun.management.jmxremote.authenticate=false
  • -Dcom.sun.management.jmxremote.ssl=false

第一个参数表示在 19999 端口监听 JMX 连接,第二个和第三个参数表示无需验证,不使用 SSL 连接,在开发测试阶段比较方便,生产环境必须指定验证方式并启用 SSL。详细参数可参考 Oracle 官方文档。这样 jconsole 可以用 ip:19999 的远程方式连接 JMX。连接后的操作是完全一样的。

许多 JavaEE 服务器如 JBoss 的管理后台都是通过 JMX 提供管理接口,并由 Web 方式访问,对用户更加友好。

在实际项目中,通过 JMX 实现配置的实时更新其实并不常用,JMX 更多地用于收集 JVM 的运行状态和应用程序的性能数据,然后通过监控服务器汇总数据后实现监控与报警。一个典型的监控系统架构如下:

┌───────────────┐   ┌───────────────┐
│  Web Console  │◀──│Metrics Server │
└───────────────┘   └───────────────┘
                            │
                            │
   ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─ ┐
     ┌───────────────┐      │
   │ │      App      │      │    │
     ├─────────┬─────┤   ┌─────┐
   │ │         │ JMX │──▶│Agent│ │
     │         └─────┤   └─────┘
   │ │      JVM      │           │
     └───────────────┘
   └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

其中,App 自身和 JVM 的的统计数据都通过 JMX 收集并发送给本机的一个 Agent,Agent 再将数据发送至监控服务器,最后以可视化的形式将监控数据通过 Web 等形式展示给用户。常用的监控系统有开源的 Prometheus 和以云服务方式提供的 DataDog 等。

练习

编写一个 MBean 统计当前注册用户数量,并在 jconsole 中查看:

下载练习

小结

在 Spring 中使用 JMX 需要:

  • 通过 @EnableMBeanExport 启用自动注册 MBean;
  • 编写 MBean 并实现管理属性和管理操作。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计5425字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7982176
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Android 的最优解?

三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Android 的最优解?

  三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Andr...
手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板 前言 大家好,我是星哥。星哥发现很多新手刚接触服务器时,都会被“选购...
飞牛NAS玩转Frpc并且配置,随时随地直连你的私有云

飞牛NAS玩转Frpc并且配置,随时随地直连你的私有云

飞牛 NAS 玩转 Frpc 并且配置,随时随地直连你的私有云 大家好,我是星哥,最近在玩飞牛 NAS。 在数...
【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024程序员】我劝你赶紧去免费领一个AWS、华为云等的主机

【1024 程序员】我劝你赶紧去免费领一个 AWS、华为云等的主机 每年 10 月 24 日,程序员们都会迎来...
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛 NAS-14:解锁公网自由!Lucky 功能工具安装使用保姆级教程 作为 NAS 玩家,咱们最...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定! 前言 作为 NAS 玩家,你是否总被这些...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...