SpringBoot特性之Actuator

简介: SpringBoot自动配置的特性,很大程度上解放了我们繁琐的配置的工作,但是也向我们屏蔽了很多内部运行 的细节,好在SpringBoot为我们提供了Actuator,Actuator在应用程序里提供了众多的Web端点,通过它 们,我们可以了解应用程序运行时的内部状况。

SpringBoot自动配置的特性,很大程度上解放了我们繁琐的配置的工作,但是也向我们屏蔽了很多内部运行
的细节,好在SpringBoot为我们提供了Actuator,Actuator在应用程序里提供了众多的Web端点,通过它
们,我们可以了解应用程序运行时的内部状况。我们可以了解Bean的组装信息,获取环境配置信息,等等
Actuator为我们提供了如下的一些端口

HTTP方法 路径 描述 Sensitive Default
GET /autoconfig 自动配置报告,记录哪些自动配置条件通过了,哪些没通过 true
GET /configprops 自动配置的属性信息 true
GET /beans 应用程序上下文里全部的Bean,以及它们的关系 true
GET /dump 获取线程活动的快照 true
GET /env 获取全部环境属性,包含环境变量和配置属性信息 true
GET /env/{name} 根据名称获取特定的环境属性值 true
GET /health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供 false
GET /info 获取应用程序的定制信息,这些信息由info打头的属性提供 false
GET /mappings 全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系 true
GET /metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数 true
GET /metrics/{name} 报告指定名称的应用程序度量值 true
GET /shutdown 优雅的关闭应用程序(endpoints.shutdown.enabled设置为true才会生效) true
GET /trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等) true
GET /loggers 展示应用程序中的日志配置信息 true
GET /heapdump 当访问这个请求的时候,会下载一个压缩的hprof的堆栈信息文件 true

我们如果要使用Actuator的话也很简单,我们首先在pom文件中引入Actuator的依赖就行了,如下:

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

然后再添加一个配置项即可:

management:
  security:
    enabled: false

下面我们访问几个来看一下功能(端口号换成自己应用的端口号):
请求:http://localhost:8003/beans
效果如下:
Beans Info
在上面的图片中,Actuator为我们展示了一个Bean的信息,Bean的名字(bean)、别名(aliases)、
scope(singleton or prototype)、类型(type)、位置(resource绝对路径)、依赖(dependencies)
请求:http://localhost:8003/autoconfig
效果如下:
autoconfig
SpringBoot的另一个重要的特性是自动配置,当我们访问/autoconfig的时候,Actuator为我们输出了
autoconfig的一些信息,自动配置这个bean需要什么样的条件。
其他的一些Actuator端点也很有意思,例如:/configprops、/mappings、/heapdump等。当然我们也可以自定义Actuator来满足自己的功能需要,demo如下所示:

package com.zkn.springboot.exercise.endpoint;

import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.stereotype.Component;

import java.lang.management.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zkn
 * @date 2017/11/15 22:50
 */
@Component
public class ThreadInfoEndpoint extends AbstractEndpoint<Map<String, String>> {

    public ThreadInfoEndpoint() {
        //id
        super("threadInfo");
    }

    /**
     * Called to invoke the endpoint.
     *
     * @return the results of the invocation
     */
    @Override
    public Map<String, String> invoke() {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        //获取所有的线程信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
        if (threadInfos != null && threadInfos.length > 0) {
            Map<String, String> map = new HashMap<>(threadInfos.length);
            for (ThreadInfo threadInfo : threadInfos) {
                map.put(threadInfo.getThreadName(), getThreadDumpString(threadInfo));
            }
            return map;
        }
        return null;
    }

    /**
     * 组装线程信息
     *
     * @param threadInfo
     */
    private String getThreadDumpString(ThreadInfo threadInfo) {

        StringBuilder sb = new StringBuilder("threadName:" + threadInfo.getThreadName() + ",threadId:" + threadInfo.getThreadId() + ",threadStatus:" + threadInfo.getThreadState());
        //锁的名字
        if (threadInfo.getLockName() != null) {
            sb.append(",lockName:" + threadInfo.getLockName());
        }
        //锁的持有者
        if (threadInfo.getLockOwnerName() != null) {
            sb.append(",lockOwnerName:" + threadInfo.getLockOwnerName());
        }
        //线程中断
        if (threadInfo.isSuspended()) {
            sb.append(",suspended:" + threadInfo.isSuspended());
        }
        if (threadInfo.isInNative()) {
            sb.append(",inNative:" + threadInfo.isInNative());
        }
        sb.append("\n");

        StackTraceElement[] stackTraceElementst = threadInfo.getStackTrace();
        MonitorInfo[] monitorInfos = threadInfo.getLockedMonitors();
        StackTraceElement stackTraceElement;
        if (stackTraceElementst != null) {
            int i;
            for (i = 0; i < stackTraceElementst.length; i++) {
                stackTraceElement = stackTraceElementst[i];
                sb.append(",stackTraceElement:" + i + ";" + stackTraceElement.toString());
                if (i == 0 && threadInfo.getLockInfo() != null) {
                    Thread.State ts = threadInfo.getThreadState();
                    switch (ts) {
                        case BLOCKED:
                            sb.append("\t-  blocked on " + threadInfo.getLockInfo());
                            sb.append('\n');
                            break;
                        case WAITING:
                            sb.append("\t-  waiting on " + threadInfo.getLockInfo());
                            sb.append('\n');
                            break;
                        case TIMED_WAITING:
                            sb.append("\t-  waiting on " + threadInfo.getLockInfo());
                            sb.append('\n');
                            break;
                        default:
                    }
                }
                for (MonitorInfo mi : monitorInfos) {
                    if (mi.getLockedStackDepth() == i) {
                        sb.append("\t-  locked " + mi);
                        sb.append('\n');
                    }
                }
            }
            if (i < stackTraceElementst.length) {
                sb.append("\t...");
                sb.append('\n');
            }

            LockInfo[] locks = threadInfo.getLockedSynchronizers();
            if (locks.length > 0) {
                sb.append("\n\tNumber of locked synchronizers = " + locks.length);
                sb.append('\n');
                for (LockInfo li : locks) {
                    sb.append("\t- " + li);
                    sb.append('\n');
                }
            }
            sb.append('\n');
        }
        return sb.toString();
    }
}

关键点是:一:继承AbstractEndpoint这个类(注意泛型类型),二:写一个无参的构造函数,调用父类的一
个有参构造函数,传入一个id描述(id描述会映射为响应的请求),三:重写invoke方法。在
AbstractEndpoint中注入Environment,所以你可以通过Environment获取系统环境变量中的值。

相关文章
|
7月前
|
消息中间件 运维 监控
|
监控 Java Spring
Springboot之Actuator的使用解析
Springboot之Actuator的使用解析 Actuator是spring boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看、相关功能统计等。
1256 0
|
监控 安全 Java
三步为你的Springboot集成Actuator监控功能
有时候我们想要实时监控我们的应用程序的运行状态,比如实时显示一些指标数据,观察每时每刻访问的流量,或者是我们数据库的访问状态等等。这时候就需要Actuator了。 使用Actuator的好处是,我们可以直接使用这个生产级别的工具,而不需要自己去实现这些东西。Actuator可以自动帮我们自动暴露出这些信息,使用HTTP或者是JMX beans的方式实现。最主要的是我们直接在properties文件中配置即可。 下面看看如何实现:
273 0
三步为你的Springboot集成Actuator监控功能
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
183 1
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
117 62
|
11天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
69 13
|
19天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
84 2
|
1月前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
3月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
基于Java+Springboot+Vue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的大学竞赛报名管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
239 3
基于Java+Springboot+Vue开发的大学竞赛报名管理系统