springboot怎么做监控?这篇总算整明白了。。。(代码片段)

Java技术栈 Java技术栈     2023-03-10     378

关键词:

作者:双子孤狼
来源:https://blog.csdn.net/zwx900102/article/details/115446997

###

任何一个服务如果没有监控,那就是两眼一抹黑,无法知道当前服务的运行情况,也就无法对可能出现的异常状况进行很好的处理,所以对任意一个服务来说,监控都是必不可少的。

就目前而言,大部分微服务应用都是基于 SpringBoot 来构建,所以了解 SpringBoot 的监控特性是非常有必要的,而 SpringBoot 也提供了一些特性来帮助我们监控应用。

本文基于 SpringBoot 2.3.1.RELEASE 版本演示。

SpringBoot 监控

SpringBoot 中的监控可以分为 HTTP 端点和 JMX 两种方式来监控当前应用的运行状况和指标收集。

| HTTP Endpoints 监控

执行器端点允许您监视应用程序并与之交互。SpringBoot 包括许多内置的端点,并允许我们添加自己的端点。可以通过 HTTP 或 JMX 启用或禁用每个端点,并公开(使其可以远程访问)。

每个端点都有一个唯一的 id,访问时可以通过如下地址进行访问:http:ip:port/id(SpringBoot 1.x )。

而在 SpringBoot 2.x 版本中,默认新增了一个 /actuator 作为基本路,访问地址则对应为:http:ip:port/actuator/id。

使用 HTTP 监控非常简单,在 SpringBoot 项目中,引入如下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

Spring Boot 基础就不介绍了,推荐下这个实战教程:https://github.com/javastacks/spring-boot-best-practice

默认就可以通过地址 http:localhost:8080/actuator/health,访问之后得到如下结果:

SpringBoot 中提供了非常多的默认端点监控,但是出于安全考虑,默认情况下有些端点并不是开启状态,如 shutdown 端点就是默认关闭的。

内置端点

SpringBoot 中默认提供的常用内置端点如下:

虽然说这里的大部分端点都是默认开启的,但是默认暴露(允许对外访问)的只有 health 和 info 端点,所以如果需要允许端点对外暴露,可以通过如下配置(如果想要暴露所有的端点,则可以直接配置 "*" ):

management:
  endpoints:
    web:
      exposure:
        include: [health,info,mappings] //或者直接配置 "*"

另外,开启或禁用某一个端点,也可以通过通过如下配置进行动态控制:

management.endpoint.<id>.enabled=true

接下来我们挑选几个重点的端点来介绍一下。

health 端点

health 断点默认只是展示当前应用健康信息,但是我们可以通过另一个配置打开详细信息,这样不仅仅会监控当前应用,还会监控与当前应用相关的其他第三方应用,如 Redis。

management:
  endpoint:
    health:
      show-details: always

这个配置打开之后,我们连接上 Redis 之后再次访问 health 端点,就可以展示 Redis 服务的健康信息了:

loggers 端点

访问 http://localhost:8080/actuator/loggers 可以查看当前应用的日志级别等信息:

这里面本身并不特别,但是有一个功能却非常有用,比如我们生产环境日志级别一般都是 info,但是现在有一个 bug 通过 info 级别无法排查,那么我们就可以临时修改 log 级别。

比如上图中的 ROOT 节点是 info 级别,那么我们可以通过 postman 等工具来发一个 post 请求修改日志级别。

修改之后就会发现,日志由原来的 info 变成了 debug:

metrics 端点

metrics 是一个非常重要的监控端点,其监控内容覆盖了 JVM 内存、堆、类加载、处理器和 tomcat 容器等一些重要指标:

可以看到这里面包含了非常多的指标,任意访问一个指标就可以查看对应的指标信息:

自定义监控端点

通过上面的介绍,可以看到 SpringBoot 提供的监控非常强大,但是就算再全面的监控也不可能满足所有人的需求,所以 SpringBoot 也支持自定义监控端点。

自定义一个监控端点主要有如下常用注解:

  • @Endpoint:定义一个监控端点,同时支持 HTTP 和 JMX 两种方式。
  • @WebEndpoint:定义一个监控端点,只支持 HTTP 方式。
  • @JmxEndpoint:定义一个监控端点,只支持 JMX 方式。

以上三个注解作用在类上,表示当前类是一个监控端点,另外还有一些注解会用在方法和参数上:

  • @ReadOperation:作用在方法上,可用来返回端点展示的信息(通过 Get 方法请求)。
  • @WriteOperation:作用在方法上,可用来修改端点展示的信息(通过 Post 方法请求)。
  • @DeleteOperation:作用在方法上,可用来删除对应端点信息(通过 Delete 方法请求)。
  • @Selector:作用在参数上,用来定位一个端点的具体指标路由。

来,一起写一个自己的监控端点,定义一个类,并使用 @Endpoint 注解标注标识,同时定义几个方法用 @ReadOperation 和 @WriteOperation 注解来标注:

@Endpoint(id="myEndpoint")
@Component
public class MyEndpoint 
    private String STATUS = "up";
    private String DETAIL = "一切正常";

//    @ReadOperation
//    public String test1()
//        return "wolf";
//    

//    @ReadOperation
//    public Map<String,String> test2()
//        Map<String,String> map = new HashMap();
//        map.put("status","up");
//        return map;
//    

    @ReadOperation
    public JSONObject test3()
        JSONObject jsonObject= new JSONObject();
        jsonObject.put("status",STATUS);
        jsonObject.put("detail",DETAIL);
        return jsonObject;
    

    @ReadOperation
    public JSONObject test3_1(@Selector String name)
        JSONObject jsonObject= new JSONObject();
        if ("status".equals(name))
            jsonObject.put("status",STATUS);
        else if ("detail".equals(name))
            jsonObject.put("detail",DETAIL);
        
        return jsonObject;
    

    @WriteOperation//动态修改指标
    public void test4(@Selector String name,@Nullable String value)
        if (!StringUtils.isEmpty(value))
            if ("status".equals(name))
                STATUS = value;
            else if ("detail".equals(name))
                DETAIL = value;
            
        
    

Spring Boot 基础就不介绍了,推荐下这个实战教程:https://github.com/javastacks/spring-boot-best-practice

@Component 注解表示将该类交给 Spring 进行管理,或者也可以再定义一个 Configuration 类来加载该 Bean 也可以。

当然,如果我们需要提供给第三方使用,如果无法保证当前包名被扫描,则需要使用 SpringBoot 的自动装配机制将该类进行管理。

@ReadOperation 方法可以返回 String 或者 JSONObject 或者 Map 集合等。

参数上加了 @Selector 注解则表示访问断端点的时候可以直接访问子节点。

完成了上面的类,启动 SpringBoot 应用,接下来就可以直接通过 http://localhost:8080/actuator/myEndpoint 进行访问了:

同时,因为 test3_1 方法使用了 @Selector 注解,所以我们可以通过这个方法每一个指标的明细:

而带有 @WriteOperation 注解的方法可以用来修改指标,这个方法需要用 post 进行访问,访问的参数可以直接使用字符串传参,也可以直接使用 json 进行传参,修改之后再次查看就可以发现指标已经被动态修改:

| JMX 监控

JMX 全称为 Java Management Extensions,即 Java 管理扩展。它提供了对 Java 应用程序和 JVM 的监控管理。

通过 JMX 我们可以监控服务器中各种资源的使用情况以及线程,内存和 CPU 等使用情况。

打开 jdk 下提供的工具 jConsole:

打开之后这里会监控到我们已经启动的应用,双击进入:

如何手动注册一个 JMX MBean?

###

定义一个接口 SystemInfoMBean(注意名字必须要用 MBean 结尾):

public interface SystemInfoMBean 
    int getCpuCore();
    long getTotalMemory();
    void shutdown();

再定义一个类实现 SystemInfoMBean 接口,实现类的明明方式为接口名去掉 MBean:

public class SystemInfo implements SystemInfoMBean 
    @Override
    public int getCpuCore() 
        return Runtime.getRuntime().availableProcessors();
    
    @Override
    public long getTotalMemory() 
        return Runtime.getRuntime().totalMemory();
    

    @Override
    public void shutdown() 
        System.exit(0);
    

最后就是需要将该实现类进行注册:

public class JmxRegisterMain 
    public static void main(String[] args) throws NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, MalformedObjectNameException, IOException 
        MBeanServer mBeanServer= ManagementFactory.getPlatformMBeanServer();
        ObjectName objectName=new ObjectName("com.lonely.wolf.note.springboot.actuator.jmx:type=SystemInfo");
        SystemInfo SystemInfo =new SystemInfo();
        mBeanServer.registerMBean(SystemInfo,objectName);//注册
        System.in.read();//防止程序结束
    

运行该 main 方法,再打开 jConsole 就可以看到成功注册了一个 MBean:

同样的,Spring 当中只要我们使用了 @Endpoint 或者 @JmxEndpoint 注解,就会自动帮我们注册一个 MBean,其原理也是利用了自动装配机制。

除了 SpringBoot 自带的监控之外,也有其他第三方开源的强大监控系统,如 Prometheus,而且 SpringBoot 也将其进行了集成,使用 Prometheus 时只需要引入如下 jar 包即可:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

当然,如果使用 Prometheus 的话需要单独安装,而且一般会选择 Prometheus + Grafana 来共同实现一个监控平台,在这里就不做过多介绍,如果感兴趣的朋友可以自己去了解下这两种软件的使用。

总结

本文主要讲述了 Spring Boot actuator 的使用,并分别介绍了其中两种监控类型 HTTP 和 JMX,最后通过一个例子来实现了自定义的端点,同时也实现了手动注册一个 MBean 的方法。

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

如果你的shiro没学明白,那么应该看看这篇文章,将shiro整合进springboot

最近在做项目的时候需要用到shiro做认证和授权来管理资源在网上看了很多文章,发现大多数都是把官方文档的简介摘抄一段,然后就开始贴代码,告诉你怎么怎么做,怎么怎么做相信很多小伙伴即使是跟着那些示例代码做完配... 查看详情

看完这篇,flinksql统统能整明白了

马云曾在一次演讲中说道:“未来的时代,将不再是IT时代,而是DT时代。”的确,这些年,越来越多开发,转行做大数据,又或通过大数据打造自己的竞争力(比如很多Java开发都会学学大数据࿰... 查看详情

看完这篇,flinksql统统能整明白了

马云曾在一次演讲中说道:“未来的时代,将不再是IT时代,而是DT时代。”的确,这些年,越来越多开发,转行做大数据,又或通过大数据打造自己的竞争力(比如很多Java开发都会学学大数据࿰... 查看详情

c++11增加的变参数模板,今天总算整明白了(代码片段)

本篇文章介绍一下c++11中增加的变参数模板template<typename..._Args>到底是咋回事,以及它的具体用法。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。按照惯例,还是先看一下本文大纲&#... 查看详情

c++11增加的变参数模板,今天总算整明白了(代码片段)

...#xff0c;那么可变参数模板和可变参数到底是什么,应该怎么使用呢,我们今天就来深究一下这些事情。1.什么是变参数模板c++11中新增加了一项内容,叫做变参数模板,所谓变参数模板,顾名思义就是参数... 查看详情

c++11增加的变参数模板,今天总算整明白了(代码片段)

...#xff0c;那么可变参数模板和可变参数到底是什么,应该怎么使用呢,我们今天就来深究一下这些事情。1.什么是变参数模板c++11中新增加了一项内容,叫做变参数模板,所谓变参数模板,顾名思义就是参数... 查看详情

像屎一样的springboot入门,总算有反应了

...,喜欢用maven这种,怎么搞都会有错误提示的玩意。搞个springboot,官方的所谓http://start.spring.io/生成的项目启动不了。猫了个咪的,开发java,估计50%的时间在搞环境,最后发现两篇好文章,总算把SpringBoot跑起来了。https://dzone.com... 查看详情

为什么redis集群要使用反向代理?看这篇就明白了

作者:等不到的口琴链接:www.cnblogs.com/Courage129/p/14351545.html如果没有反向代理,一台Redis可能需要跟很多个客户端连接:看着是不是很慌?看没关系,主要是连接需要消耗线程资源,没有代理的话,Redis要将很大一部分的资源用在... 查看详情

java商城项目的常用框架,看完这篇彻底明白了

正文做了3~5年编程开发,你已经积累了不少项目经验,扩宽了技术广度,也许已发力成为团队管理者。到了这个阶段,大家却常有这种感受:感觉自己卡在瓶颈进步缓慢,技术水平很难像早期一样实现大幅... 查看详情

javaweb会话的学习笔记:cookie和session的知识点,这一次我总算学明白了

@[Toc]1会话1.1什么是会话?用户打开浏览器,访问Web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。1.2会话跟踪一种维护浏览器状态的方法,服务器需要识别多次请求是否来... 查看详情

javaweb会话的学习笔记:cookie和session的知识点,这一次我总算学明白了

@[Toc]1会话1.1什么是会话?用户打开浏览器,访问Web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。1.2会话跟踪一种维护浏览器状态的方法,服务器需要识别多次请求是否来... 查看详情

flutter帧率监控|由浅入深,详解获取帧率的那些事

前言做线上帧率监控上报时,少不了需要弄明白如何通过代码获取实时帧率的需求,这篇文章通过图解配合Flutter性能调试工具的方式一步步通俗易懂地让你明白获取帧率的基础知识,以后再也不愁看不懂调试工具上指标了。说... 查看详情

我的虚拟内存怎么是e盘?怎么改教教我、进来看看图片、还是我没整明白

参考技术A1、鼠标右健点击“我的电脑”,打开属性;2、点击“高级”,打开“设置”;3、鼠标点在C上,依次点:无分页文件、设置:4、返回设置:4、依次点:D、自定义大小、输入虚似内存数字、设置、确定;5、虚似内存一... 查看详情

前两天遇到了错误好久才整明白给大家分享下:

错误:(Networkerror[errno60]:SSLcertificateproblem,verifythattheCAcertisOK.Details:error:14090086:SSLroutines:SSL3_GET_SERVER_CERTIFICATE:certificateverifyfailed)这个错误是证书验证不通过,解决思路: 首先查看自己的openssl扩展开 查看详情

springboot应用启动过程分析

真的好奇害死猫!之前写过几个SpringBoot应用,但是一直没搞明白应用到底是怎么启动的,心里一直有点膈应。好吧,趁有空去看了下源码,写下这篇博客作为学习记录吧!个人拙见,若哪里有理解不对的地方,请各路大神指正... 查看详情

springboot服务监控,健康检查,线程信息,jvm堆信息,指标收集,运行情况监控等!

...微服务应用全部监控起来的任务。我们的微服务应用都是SpringBoot应用,因此就自然而然的想到了借助SpringBoot的Actuator模块。本篇是我在完成这个工单之后,对SpringBootActuator模块学习应用的总结。在本篇文章中,你可以学习到:1... 查看详情

链表,画几下就整明白了!

大家好呀,我是蛋蛋。数组的文章中给臭宝们说过,连续的内存使得数组在进行插入和删除时需要移动大量元素,这就意味着要耗费时间。在数据结构与算法中,快男才是大家的最爱,像插入和删除这么持久... 查看详情

python常用函数三都有哪些?这7个函数使用频率最高,总算搞明白了

参考技术A1.1例如:print(hex(2))案例1.2输出函数:print(hex(2))1.3输出结果:0x21.4解析说明:返回16进制的数。2.1例如:print(chr(10))案例2.2输出函数:print(chr(10))2.3输出结果:0o122.4解析说明:返回当前整数对应的ASCll码3.1例如:print(ord("b... 查看详情