右耳菌-邓小白的Java架构师的修炼之路spring.io

SpringBoot 使用Actuator 管理你的Spring

2022-07-20  本文已影响0人  右耳菌

一、Actuator介绍

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

二、端点配置

Spring Boot包含许多内置端点,允许添加自己的端点,可以配置端点是否对外开放或关闭。

  1. 设置默认关闭所有端点(默认开放启用了“health”和“info”)
    management.endpoints.enabled-by-default = false
  1. 启动指定的端点
    management.endpoint.info.enabled = true
  1. 数据缓存
    端点自动缓存对不带任何参数的读取操作的响应。要配置端点缓存响应的时间量
    management.endpoint.<name>.cache.time-to-live = 10s
    <name>需要使用对应的端点名称来代替。

三、Http端点配置

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management.endpoints.web.cors.allowed-origins = http://example.com
management.endpoints.web.cors.allowed-methods = GET,POST

1. 端点讲解 - Health 健康检查

访问/actuator/health查看程序中组件检查项的运行状况信息,在出现故障时能及时发现。Spring Boot默认提供了对Redis、RabbitMQ、DataSource、MongoDB等组件的检查项。

  • 展示更详细内容(默认never)
    management.endpoint.health.show-details=never (或者when-authorized | always)
  • 返回结果
    如果有检查项处于非检查状态,Http状态码为503,返回值为DOWN或者OUT_OF_SERVICE如果没有检查初问题,返回Http状态码200,返回值UP或者UNKNOWN
  • 自定义健康检查项
    实现HealthIndicator接口,通过spring实例化一个对象,Spring Boot会自动触发健康检查,并归入health的结果。
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;

import java.util.Random;

/**
 * 自定义检查项
 */
@Component
public class MyHealthcheck extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        // 测试,具体怎么检查,看你的业务细节
        int i = new Random().nextInt();
        if (i % 2 == 0) {
            builder.withDetail("细节", "1").up();
        } else {
            builder.withDetail("细节", "2").down();
        }
    }
}

结果
2. 端点讲解 - 日志配置
  • logging.level.root = WARN
  • logging.level.org.springframework.web= DEBUG
  • logging.level.org.hibernate = ERROR
curl -X POST -H 'Content-Type: application/json' -i 'http://127.0.0.1:8081/manage/loggers/ROOT' --data '{
"configuredLevel": "DEBUG"
}'

3. 端点讲解 - metrics

Metrics是生产应用中很重要功能,简单可理解为对运行时具体功能的监控。Spring Boot中集成micrometer实现

  • 支持查看哪些数据?
    通过/actuator/metrics查看所有支持的信息,/metrics/{requiredMetricName}查看指定某一项指标JVM内存、线程、GC信息、类加载情况、CPU指标、Http请求统计、Tomcat信息…等等
  • 与监控系统的集成
    支持将数据导出到:AppOptics、Atlas、Datadog、Dynatrace、Elastic、Ganglia、Graphite、Humio、Influx、JMX、KairosDB、New Relic、Prometheus、SignalFx、Simple (in-memory)、StatsD、Wavefront
  • 自定义监控指标
    代码中注入MeterRegistry对象,然后进行手动注册
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

@Component
public class MyMetrics {

    private final List<String> words = new CopyOnWriteArrayList<>();

    public MyMetrics(MeterRegistry meterRegistry) {
        meterRegistry.gaugeCollectionSize("dictionary.size", Tags.empty(), this.words);
    }
}

四、自定义端点

可以理解为“概念上类似SpringMVC的controller写法,却又是完全不同的一套APl。”

import org.springframework.boot.actuate.endpoint.annotation.*;
import org.springframework.stereotype.Component;

@Endpoint(id = "myEndpoint")
@Component
public class MyEndPoint {

    String name = "default";

    @ReadOperation
    public String getName() {
        // spring http端点的json格式
        return "{\"name\":\"" + name + "\"}";
    }

    @DeleteOperation
    public void delName() {
        name = "";
    }

    @WriteOperation
    public void setName(@Selector String name) {
        this.name = name;
    }

}

五、快速理解JMX机制

Java Management Extensions (JMX)提供了一种监视和管理应用程序的标准机制。tomcat、kafka、druid都是用的JMX技术来实现对外暴露管理接口和监控信息。

  • 如何Jconsole工具通过JMX技术实现对应用的监控和管理?
  • 通过Spring框架快速增加自定义Mbean
    默认情况下,Spring Boot将管理端点公开为org.springframework.boot域下的JMX MBean。
  • 通过JMX公开所有端点并仅显示端点health和info端点
    management.endpoints.jmx.exposure.exclude=*
    management.endpoints.jmx.exposure.include=info, health

例子

public interface JmxTestMBean {
    public String getName();
    public void setName(String name);
    public String printHello();
    public String printHello(String whoName);
}
import org.springframework.stereotype.Component;

@Component
public class JmxTest implements JmxTestMBean {
    private String name;
     
    @Override
    public String getName() {
        return name;
    }
  
    @Override
    public void setName(String name) {
        this.name = name;
    }
  
    @Override
    public String printHello() {
        return "JmxTest "+ name;
    }
  
    @Override
    public String printHello(String whoName) {
        return "JmxTest  " + whoName;
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/7/20 9:47
 */
public class TestJMXRegListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    JmxTest jmxTest;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
            // create mbean server
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            // create object name
            ObjectName objectName = null;
            objectName = new ObjectName("jmxBean:name=testJM1X");
            // 注册
            server.registerMBean(jmxTest, objectName);
            /**
             * JMXConnectorServer service
             */
            // 这句话非常重要,不能缺少!注册一个端口,绑定url后,客户端就可以使用rmi通过url方式来连接JMXConnectorServer
            Registry registry = LocateRegistry.createRegistry(1099);

            // 构建JMXServiceURL
            JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi://jndi/rmi://localhost:1099/jmxrmi");
            // 创建JMXConnectorServer
            JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server);
            // 启动
            cs.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

上一篇下一篇

猜你喜欢

热点阅读