大家好,我是磊哥。
概述
Spring Boot 有一个非常好用的监控和管理的源软件,这个软件就是 Spring Boot Admin。该软件能够将 Actuator 中的信息进行界面化的展示,也可以监控所有 Spring Boot 应用的健康状况,提供实时警报功能。
主要的功能点有:
- 
显示应用程序的监控状态 
- 
应用程序上下线监控 
- 
查看 JVM,线程信息 
- 
可视化的查看日志以及下载日志文件 
- 
动态切换日志级别 
- 
Http 请求信息跟踪 
- 
其他功能点…… 
项目地址:
https://github.com/codecentric/spring-boot-admin
搭建服务流程说明
- 
admin-server admin 监控服务 
- 
admin-order amdin 客户端服务 
创建Spring Boot Admin项目
版本说明:版本建议: Spring Boot 2.x=Spring Boot Admin 2.x(比如Spring Boot 2.3.x 可以用Spring Boot Admin 2.3.x)
创建一个 Spring Boot 项目,用于展示各个服务中的监控信息,加上 Spring Boot Admin 的依赖,具体代码如下所示
pom 依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
 </parent>
 
<properties>
        <java.version>1.8</java.version>
        <spring.cloud.alibaba.version>2.2.5.RELEASE</spring.cloud.alibaba.version>
        <spring.boot.version>2.3.6.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR8</spring.cloud.version>
        <admin.starter.server.version>2.3.1</admin.starter.server.version>
    </properties>
 
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
     <groupId>de.codecentric</groupId>
     <artifactId>spring-boot-admin-starter-server</artifactId>
     <version>${admin.starter.server.version}</version>
</dependency>
启动类
添加@EnableAdminServer
@EnableAdminServer
@SpringBootApplication
public class AdminServerApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(AdminServerApplication.class,args);
    }
}
yml 配置
在属性文件中增加端口配置信息:
server:
  port: 8000
 
spring:
  application:
    ## 注册服务名
    name: admin-order
 
management:
  endpoint:
    health:
      show-details: always
启动程序,访问 Web 地址 http://127.0.0.1:8000/ 就可以看到主页面了,这个时候是没有数据的,如图 1 所示

客户端服务
流程
创建amdin-order 服务,将服务注册到 admin-server 中
pom 依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
    </parent>
 
    <properties>
        <java.version>1.8</java.version>
        <spring.cloud.alibaba.version>2.2.5.RELEASE</spring.cloud.alibaba.version>
        <spring.boot.version>2.3.6.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR8</spring.cloud.version>
        <spring.boot.admin.client.version>2.3.1</spring.boot.admin.client.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>${spring.boot.admin.client.version}</version>
        </dependency>
      
    </dependencies>
yml 配置
spring:
  application:
    ## 注册服务名
    name: admin-order
  ## spring boot admin
  boot:
    admin:
      client:
        api-path:
        url: http://127.0.0.1:8000
        instance:
          prefer-ip: true # 使用ip注册进来
 
 
server:
  port: 8100
 
#  endpoints config
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    enabled-by-default: true
    web:
      base-path: /actuator
      exposure:
        include: '*'
启动 admin-order 服务
@SpringBootApplication
public class AdminOrderApp {
 
    public static void main(String[] args) {
        SpringApplication.run(AdminOrderApp.class,args);
    }
 
}
从新刷新 admin 平台,admin-order 服务就可以监控

- 
绿色:健康 
- 
灰色:连接客户端健康信息超时(超过10s) 
- 
红色:就能看到具体异常信息 
Spring Boot Admin 监控平台
Insighs 信息
自定义的 Info 信息、健康状态、元数据,如图

Endpoint 端点接口信息

JVM 信息

Admin 中查看各个服务的日志
客户端需要把日志同步ADMI服务中,通过JMX,客户端配置如下
添加 logback-spring.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<!--
    小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
    <properties>
        <log-path>/Users/lengleng</log-path>
    </properties>
    1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
    2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="false" scan="false">
 <property name="log.path" value="logs/admin-order"/>
 <!-- 彩色日志格式 -->
 <property name="CONSOLE_LOG_PATTERN"
     value="${CONSOLE_LOG_PATTERN:-%(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %(${LOG_LEVEL_PATTERN:-%5p}) %(${PID:- }){magenta} %(---){faint} %([%15.15t]){faint} %(%-40.40logger{39}){cyan} %(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
 <!-- 彩色日志依赖的渲染类 -->
 <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
 <conversionRule conversionWord="wex"
     converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
 <conversionRule conversionWord="wEx"
     converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
 <!-- Console log output -->
 <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
   <pattern>${CONSOLE_LOG_PATTERN}</pattern>
  </encoder>
 </appender>
 
 <!-- Log file debug output -->
 <appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <file>${log.path}/debug.log</file>
  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
   <fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
   <maxFileSize>50MB</maxFileSize>
   <maxHistory>30</maxHistory>
  </rollingPolicy>
  <encoder>
   <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
  </encoder>
 </appender>
 
 <!-- Log file error output -->
 <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <file>${log.path}/error.log</file>
  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
   <fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
   <maxFileSize>50MB</maxFileSize>
   <maxHistory>30</maxHistory>
  </rollingPolicy>
  <encoder>
   <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
  </encoder>
  <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
   <level>ERROR</level>
  </filter>
 </appender>
 
 <logger name="org.activiti.engine.impl.db" level="DEBUG">
  <appender-ref ref="debug"/>
 </logger>
 
 
 <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
 <root level="INFO">
  <appender-ref ref="console"/>
  <appender-ref ref="debug"/>
 </root>
</configuration>
yml 配置
management:
  endpoints:
    web:
      exposure:
        include: '*'
    enabled-by-default: true
  endpoint:
    health:
      show-details: ALWAYS
    # 日志记录
    logfile:
      external-file: D:/project/springcould-alibaba-example/logs/admin-order/debug.log
Spring Boot Admin 查询日志
从新打Admin 监控平台,点击 admin-order 服务查看日志,如下

访问admin-order 接口
@Slf4j
@RestController
public class OrderController {
 
    @GetMapping("getOrder")
    public String getOrder() {
        log.info("getOrder.execute");
        Date date = new Date();
        // SimpleDateFormat
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(date);
        log.info("getOrder.resp 记录当前时间:普通时间: {}", time);
        return "admin order cliect hello";
    }
}
访问http://127.0.0.1:8100/getOrder 查看日志文件

日志文件等级配置

Admin 中 SpringSecurity
pom 依赖
 <!-- security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
SecuritySecureConfig
@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
 
    private final String adminContextPath;
 
    public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
        this.adminContextPath = adminServerProperties.getContextPath();
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter( "redirectTo" );
 
        http.authorizeRequests()
                .antMatchers( adminContextPath + "/assets/**" ).permitAll()
                .antMatchers( adminContextPath + "/login" ).permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage( adminContextPath + "/login" ).successHandler( successHandler ).and()
                .logout().logoutUrl( adminContextPath + "/logout" ).and()
                .httpBasic().and()
                .csrf().disable();
    }
}
yml 配置
spring:
  security:
    user:
      name: "admin"
      password: "admin"
从新启动 admin-server 服务

客户端注册 admin 服务需要配置 username 和 password
spring:
  application:
    ## 注册服务名
    name: admin-order
  ## spring boot admin
  boot:
    admin:
      client:
        api-path:
        url: http://127.0.0.1:8000
        instance:
          prefer-ip: true # 使用ip注册进来
        username: admin
        password: admin
Nacos 拉取客户端
不懂Nacos 怎样作为注册中心,可以查看:
https://mp.csdn.net/mp_blog/creation/editor/121676330
pom 依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
    </parent>
 
    <properties>
        <java.version>1.8</java.version>
        <spring.cloud.alibaba.version>2.2.5.RELEASE</spring.cloud.alibaba.version>
        <spring.boot.version>2.3.6.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR8</spring.cloud.version>
        <admin.starter.server.version>2.3.1</admin.starter.server.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>${admin.starter.server.version}</version>
        </dependency>
       <!-- security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
       
        <!--alibaba-nacos-discovery(阿里注册中心discovery)-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
 
    <dependencyManagement>
        <dependencies>
            <!--Spring Cloud 相关依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--Spring Cloud Alibaba 相关依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
yml 配置
group: ADMIN 作为一组监控服务,服务端可以拉取客户端配置为 group:ADMIN
spring:
  application:
    ## 注册服务名
    name: admin-server
 
  security:
    user:
      name: "admin"
      password: "admin"
 
  cloud:
    nacos:
      ## 注册中心地址
      discovery:
        server-addr: 127.0.0.1:8848
        group: ADMIN
客户端同服务端配置 (也要从新注册到 Nacos 服务)
邮件配置
 <!-- mail -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
yml 配置
spring:
  mail:
    host: smtp.qq.com # 发件人使用的qq邮箱服务
    username: 865391093@qq.com
    # 授权码,不是密码,在qq邮箱设置‐账号里面有生成授权码
    password: zaydkxfjbjwbbgbc
  boot:
    admin:
      notify:
        mail:
          # 发件人
          from: 865391093@qq.com
          # 收件人,多个中间用,分隔
          to: 865391093@qq.com
qq 邮箱设置

测试

自定义端点配置
Indicator
/**
 *  自定义 dicator
 */
@Component
public class MyHealthIndicator implements HealthIndicator {
 
 
    @Override
    public Health health() {
 
        int errorCode = check(); // perform some specific health check
        if (errorCode != 0) {
            return Health.down().
                    withDetail("msg","error service").
                    withDetail("code",500).
                    build();
        }
        return Health.up().build();
    }
 
    private int check() {
        return 0;
    }
}
info
/**
 * 自定义 info
 */
@Component
public class AppInfo implements InfoContributor {
 
 
    @Override
    public void contribute(Info.Builder builder) {
 
        builder.withDetail("version","1.0.RELEASE");
        builder.withDetail("project","admin-order");
 
    }
}
yml 配置
info:
  appName: admin-order
  mavenAppName: '@project.artifactId@'
  mavenVersion: '@project.version@'
ADMIN 控制台查看

Metrics
Spring Boot Actuator 为 Micrometer 提供了依赖管理和自动配置功能,Micrometer 是一个应用指标 facade(面门),支持多种监控系统,包括:
AppOptics,Azure Monitor,Netflix Atlas,CloudWatch,Datadog,Dynatrace,Elastic,Ganglia,Graphite,Humio,Influx/Telegraf,JMX,KairosDB,New Relic,Prometheus,SignalFx,GoogleStackdriver,StatsD和 Wavefront。
- 
提供一些列api供我们操作指标 
- 
提供了缓存、类加载器、GC、jvm内存、cpu 利用率、线程...指标 能够开箱即用 
- 
已经融入 springboot Actuator 
JVM度量,报告利用率(JVM metrics, report utilization of):
- 
各种内存和缓冲池( Various memory and buffer pools) 
- 
与垃圾收集有关的统计数据( Statistics related to garbage collection) 
- 
线程利用率( Threads utilization) 
- 
加载/卸载的类数( Number of classes loaded/unloaded) 
@RestController
public class HelloController {
 
    @GetMapping("/sayHi")
    public String sayHi(String productNo) throws InterruptedException {
        // 线程长请求
        //Thread.sleep(5000);
        // 定制基于Metrics的计数器
        Metrics.counter("order.counter","productNo",productNo).increment();
 
        // 定制基于Metrics的定时器
        Timer timer = Metrics.timer("order.timer");
        timer.record(()->{
            System.out.println("success");
        });
 
        // 定制基于Metrics的仪表  记录单个值  一般集合数量
        Metrics.gauge("order.gauge",1);
 
        // 定制基于Metrics的摘要 一般用来记录 百分比数值(缓存命中率)
        DistributionSummary summary = Metrics.summary("redis.hitRate");
        summary.record(1.5);
        return "success";
    }
}
增加定制 Metrics
Counter
Counter 是一种比较简单的Meter,它是一种单值的度量类型,或者说是一个单值计数器。
使用场景:
Counter 的作用是记录XXX的总量或者计数值,适用于一些增长类型的统计,例如下单、支付次数、Http请求总量记录等等
// 定制基于Metrics的计数器
Metrics.counter("order.counter","produntNo",produntNo).increment();
测试
127.0.0.1:8100/actuator/metrics/order.counter
{
 "name": "order.counter",
 "description": null,
 "baseUnit": null,
 "measurements": [{
  "statistic": "COUNT",
  "value": 3.0
 }],
 "availableTags": [{
  "tag": "productNo",
  "values": ["G122390"]
 }]
}

Timer
Timer(计时器)适用于记录耗时比较短的事件的执行时间,通过时间分布展示事件的序列和发生频率。
使用场景:
根据个人经验和实践,总结如下:
- 
记录指定方法的执行时间用于展示。 
- 
记录一些任务的执行时间,从而确定某些数据来源的速率,例如消息队列消息的消费速率等。 
// 定制基于Metrics的定时器
Timer timer = Metrics.timer("xushu.timer");
timer.record(()->{
    System.out.println("success");
});
Summary
Summary(摘要)主要用于跟踪事件的分布,在Micrometer中,对应的类是DistributionSummary(分发摘要)。它的使用方式和Timer
十分相似,但是它的记录值并不依赖于时间单位。
使用场景:
根据个人经验和实践,总结如下:
不依赖于时间单位的记录值的测量,例如服务器有效负载值,缓存的命中率等。
// 定制基于Metrics的摘要 一般用来记录 百分比数值(缓存命中率)
DistributionSummary summary = Metrics.summary("redis.hitRate");
summary.record(1.5);
原文cnblogs.com/keatsCoder/p/12934394.html
近期技术热文
往期推荐
文章评论