写于:2019-10-05 12:11:30 版本:Spring Boot Admin 2.1.6 Spring Boot 2.1.5.RELEASE

Spring Boot Admin 是 《Spring Boot Actuator 应用监控》 的图形化界面。

一、图形化界面:Spring Boot Admin

官网对 Spring Boot Admin 给出了说明

The UI is just a Vue.js application on top of the Spring Boot Actuator endpoints.

在提供有 Actuator 能力的 Spring Boot 应用,通过 HTTP 请求的方式,能够获取到 Spring Boot 应用相关的监测数据。但监测数据都是以 JSON 文本的格式进行展示,不利于阅读分析,且当应用存在多实例时,进行数据分析更困难。于是出现针对 Actuator 的图形化管理界面 **Spring Boot Admin**

二、Spring Boot Admin 相关UI 界面展示

2.1、Security 安全登录

通过引入:spring-security 实现 Spring Boot Admin 后台的安全校验

04.png

监控应用列表

展示当前监测的应用列表

Spring Boot Admin - Actuator监控图形化界面_UI展示]监控应用列表
05.png

监控应用面板

展示当前监测应用的图形数据

06.png
用事件变更日志

Spring Boot Admin 请求相关应用 /actuator/* 监测数据的日志数据

07.png

应用详细监控信息

单个应用实例的相关监测数据

  • info、health 信息

08.png

  • 应用进程进程、线程、堆栈内存监控信息

09.png

  • 实时日志打印

10.png

  • Http 请求监控

11.png
更多内容,查看官网。

Spring Boot Admin 存在的意义:对 Spring Boot Actuator 文本监测数据进行图形化。

三、启动一个简单的 Spring Boot Admin 应用

Spring Boot Admin 支持两种应用监控方式:

  • 服务注册方式进行应用监控
  • 通过SBA client 端 进行监控信息上报

演示:Eureka 服务注册方式实现应用监控( 更多介绍,参考 Spring Boot Admin 官方网站)

3.1、服务介绍

服务名称 端口号 作用
feign-register 1111 服务注册中心
feign-SBA-server 9999 Spring Boot Admin 服务端
feign-consumer 9527 被监控服务

忽略注册中心(feign-register) 和 被监控服务(feign-consumer) 细节,只关注 监控配置详情

3.2、构建 Spring Boot Admin 服务端

1、依赖

A、Spring Boot Admin Server 依赖

  1. <dependency>
  2. <groupId>de.codecentric</groupId>
  3. <artifactId>spring-boot-admin-starter-server</artifactId>
  4. <version>2.1.6</version>
  5. </dependency>

B、Eureka Client 依赖

  1. <!-- eureka client -->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  5. </dependency>

C、Security 依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-security</artifactId>
  4. </dependency>

2、application.properties 配置

A、Security 配置

  1. # security 账户名密码
  2. spring.security.user.name = sba-wtf-user
  3. spring.security.user.password = sba-wtf-pwd

B、Eureka 注册配置

  1. ## eureka 服务地址
  2. eureka.client.service-url.defaultZone = http://user-wtf:pwd-wtf@localhost:1111/eureka/
  3. eureka.instance.prefer-ip-address = true
  4. eureka.client.registry-fetch-interval-seconds = 5
  5. eureka.instance.lease-renewal-interval-in-seconds = 10
  6. ## eureka 健康检查端口配置
  7. eureka.instance.health-check-url = http://localhost:${server.port}/actuator/health
  8. eureka.instance.status-page-url = http://localhost:${server.port}/actuator/info
  9. eureka.instance.home-page-url = http://localhost:${server.port}/

3.3、客户端配置

1、引入 spring-boot-starter-actuator 依赖

2、application.properties 配置

A、开放 actuator 访问端口

  1. ## 开放 actuator 端点访问(可以根据需求进行控制)-更多内容参考官方文档
  2. management.endpoints.web.exposure.include = *
  3. management.endpoint.health.show-details = always

B、Eureka 注册

  1. ## eureka 服务地址
  2. eureka.client.service-url.defaultZone = http://user-wtf:pwd-wtf@localhost:1111/eureka/
  3. eureka.instance.prefer-ip-address = true
  4. eureka.client.registry-fetch-interval-seconds = 5
  5. eureka.instance.lease-renewal-interval-in-seconds = 10
  6. eureka.instance.health-check-url = http://${spring.cloud.client.ip-address}:${server.port}/actuator/health
  7. eureka.instance.status-page-url = http://${spring.cloud.client.ip-address}:${server.port}/actuator/info
  8. eureka.instance.home-page-url = http://${spring.cloud.client.ip-address}:${server.port}/
  9. ## 上报 Spring Boot Client 的账号、密码
  10. eureka.instance.metadata-map.user.name = 客户端应用security认证用户名
  11. eureka.instance.metadata-map.user.password = 客户端应用security认证用户密码
  12. eureka.instance.metadata-map.management.address = ${spring.cloud.client.ip-address}
  13. eureka.instance.metadata-map.management.port = ${server.port}

3.4、定制化 Spring Boot Admin

1、定制化 actuator Url 访问前缀

主要配置:

  1. ## 自定义 actuator 请求前缀
  2. management.endpoints.web.base-path = /wtf/actuator

关联的 eureka 配置修改:修改健康检查 Url 配置

  1. eureka.instance.health-check-url = http://${spring.cloud.client.ip-address}:${server.port}${management.endpoints.web.base-path}/health
  2. eureka.instance.status-page-url = http://${spring.cloud.client.ip-address}:${server.port}${management.endpoints.web.base-path}/info
  3. eureka.instance.home-page-ur= http://${spring.cloud.client.ip-address}:${server.port}$/
  4. eureka.instance.metadata-map.management.context-path = ${management.endpoints.web.base-path}

2、定制化 actuator访问端口 port

主要配置:

  1. ## 自定义 actuator 访问端口
  2. management.server.port = 9528

关联的 eureka 配置修改:健康检查 和 访问端口

  1. eureka.instance.health-check-url = http://${spring.cloud.client.ip-address}:${management.server.port}/health
  2. eureka.instance.status-page-url = http://${spring.cloud.client.ip-address}:${management.server.port}/info
  3. eureka.instance.home-page-url = http://${spring.cloud.client.ip-address}:${management.server.port}/
  4. eureka.instance.metadata-map.management.port = ${management.server.port}

3、Spring Boot Admin Server 定制化 logo

A、resource 目录下:创建:META-INF/spring-boot-admin-server-ui/img 目录

B、META-INF/spring-boot-admin-server-ui/img 中放入:logo 图片 - ui-brand-logo.jpg

C、在  application.properties 中配置

  1. # 标签页标题 title
  2. spring.boot.admin.ui.title = WTF Monitoring Platform
  3. # 标签页 favicon 图片
  4. spring.boot.admin.ui.favicon=img/ui-brand-logo.jpg
  5. # 标题栏图片
  6. spring.boot.admin.ui.brand = <img src=\"img/ui-brand-logo.jpg\"><span>WTF Monitoring</span>

结果展示:
12.png
更多定制信息,参考官方文档

4、集成 Hystrix Dashboard(无法集成Turbine 聚合面板)

Spring Boot Admin 2.x 不在支持 Hystrix Dashboard
image.png
通过引入第三方组件,实现 Hystrix Dashboard 面板

A、引入相关maven依赖(Git Hub 仓库地址

  1. <dependency>
  2. <groupId>nl.devillers</groupId>
  3. <artifactId>spring-boot-admin-hystrix-dashboard</artifactId>
  4. <version>1.0.2</version>
  5. </dependency>

B、添加 Hystrix 注解(可不加,据版本而定),还有开启 hystrix.stream 端点访问(具体查询 actuator 官方文档)
image.png
C、关注点(HystrixCommand 熔断需要添加 Fallback 处理逻辑,否则服务上报到 Hystrix Dashbaord 中)
D、效果
image.png

5、集成邮箱报警

服务上下线、健康信息报警推送

A、添加依赖

  1. <!-- email model -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-mail</artifactId>
  5. </dependency>

B、application 添加配置信息

  1. # email 相关配置
  2. spring.mail.host = smtp.exmail.qq.com
  3. spring.mail.username = 邮箱名
  4. spring.mail.password = 邮箱码(非密码)
  5. spring.mail.port = 465
  6. spring.boot.admin.notify.mail.to = 邮箱名(接收者,多个逗号分隔)
  7. spring.boot.admin.notify.mail.from = 邮箱名(即发送者)
  8. spring.mail.properties.mail.debug = true
  9. spring.mail.properties.mail.smtp.auth = true
  10. spring.mail.properties.mail.smtp.ssl.enable = true
  11. spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory

6、Security 多用户登录

Spring Boot Admin 安全校验借助 Spring Security 完成,多用户的支持,即:Spring Security 多用户配置。
以,基于内存方式为例(基于Mysql等存储介质,借助 UserDetailService 等机制可实现),相关配置如下:

  1. @Configuration
  2. public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
  3. // 省略 ......
  4. @Override
  5. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  6. // 密码编码器
  7. BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
  8. // 基于内存的用户名密码
  9. // 注册账号
  10. auth.inMemoryAuthentication()
  11. .withUser("userName")
  12. .password(passwordEncoder.encode("password"))
  13. .roles("register");
  14. // 游客账号
  15. auth.inMemoryAuthentication()
  16. .withUser("tourist")
  17. .password(passwordEncoder.encode("tourist"))
  18. .roles("tourist");
  19. }
  20. }

7、自定义 Spring Security Filter 校验

项目中,可能存在项目模块使用的 Spring Security 进行权限控制。且需要将用户认证和自身已有认证进行剥离时,通过自定义认证 Filter ,实现对应的认证。
关键代码如下:(直接参考:BasicAuthenticationFilter进行修改即可)
image.png

8、集成 javaMelody

JavaMelody GitHub JavaMelody Spring Boot Admin UI:仅支持 spring boot admin 1.x版本 Spring Boot 集成 JavaMelody

8.1、应用集成 javaMelody

HikariCP数据源报错ISSUES 解决

引入依赖
  1. <dependency>
  2. <groupId>net.bull.javamelody</groupId>
  3. <artifactId>javamelody-spring-boot-starter</artifactId>
  4. <version>1.91.0</version>
  5. </dependency>

基础配置

javamelody 基于 Spring Boot Actuaotr 端口进行监控端口暴露,基础配置如下:

  1. management.server.port = ${server.port}
  2. ## javamelody monitoring
  3. javamelody.management-endpoint-monitoring-enabled = true

界面监控信息访问

访问 http://ip:port/actuator/monitoring

image.png

8.2、Spring Boot Admin 集成 JavaMelody UI

官方提供的ui组件仅支持 Spring Boot Admin 1.x ,所以需要定制化ui界面。

TODO Spring Boot Admin 2.x 不在支持,需要定制化,涉及 vue 前端代码定制

3.5、Spring Boot Admin 引入项目中,踩过的坑

问题1、Spring Boot Admin Server 启动报错:Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]

原因: Spring Boot Admin 2.1.6 与 Tomcat 9.X 存在冲突

解决:

  • 1、降低 Tomcat 版本 ```xml org.springframework.boot spring-boot-starter-web org.springframework.boot

org.apache.tomcat.embed tomcat-embed-core 8.5.31

  1. - 2、使用 netty 作为容器
  2. ```xml
  3. <!-- 移除 web tomcat -->
  4. <dependency>
  5. <groupId>org.springframework.boot</groupId>
  6. <artifactId>spring-boot-starter-web</artifactId>
  7. <exclusions>
  8. <exclusion>
  9. <groupId>org.springframework.boot</groupId>
  10. </exclusion>
  11. </exclusions>
  12. </dependency>
  13. <!-- 引入 netty -->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-jetty</artifactId>
  17. </dependency>

问题2、项目中存在 context-path 配置时,无法进行正常监控问题

原因:context-path 的增加改变了原有 /actuator 的访问路径

解决

  • 1、修改 /actuator 访问端口,与 web 应用区分。
    如上面:定制化 /actuator 访问端口
  • 2、直接修改 Spring Boot Admin 的监控请求路径
    配置如下:(全部配置)
    1. # 健康检查配置,增加 ${server.servlet.context-path} 前缀
    2. eureka.instance.health-check-url = http://${spring.cloud.client.ip-address}:${server.port}${server.servlet.context-path}/health
    3. eureka.instance.status-page-url = http://${spring.cloud.client.ip-address}:${server.port}${server.servlet.context-path}${management.endpoints.web.base-path}/info
    4. eureka.instance.home-page-url = http://${spring.cloud.client.ip-address}:${server.port}${server.servlet.context-path}/
    5. eureka.instance.metadata-map.management.context-path = ${server.servlet.context-path}
    6. eureka.instance.metadata-map.management.address = ${spring.cloud.client.ip-address}
    7. eureka.instance.metadata-map.management.port = ${server.port}

    12.png

    问题3、HttpTrace 页面无法访问,out of Memory 问题

    Spring Boot Admin UI 处理 timestamp 格式时有问题,会存在内存泄露问题。
    image.png
    官方 GitHub issue 问题讨论
    Spring Boot 2.1.18 关于 Actuator API 问题:timestamp 必须是 ISO 8610

方法一:全局变更时间json 转换为支持 ISO 8610

剔除相关:_spring.jackson.serialization.write-dates-as-timestamps=true_配置。
问题局限性:Spring Boot 默认使用的 jackson(其他Json 框架同),如果服务默认事件格式转换为时间戳,全局配置,会影响业务 API 的时间处理。

方法二:重写 HttpTrace Endpoint ,覆盖原有 httptrace Endpoint

该方法的局限性,也很明显:当 版本升级针对 httptrace 的数据结果,或者逻辑发生变更,需要同步进行相关内容的变更

首先看一下 /actuator/httptrace 得到的结果结构:
image.png
问题的关键在于 Spring Boot Admin Server UI 在处理 HttpTrace 时,timestamp 格式必须时 ISO 8610 ,否则会导致界面死循环最后浏览器崩溃。

通过 官方文档 ,以及/actuator/httptrace返回结构知道,Spring Boot Actuator 端点 /actuator/httptrace返回结构中 timestamp 字段为字符串,
image.png

针对全局的时间json处理无法支持 ISO 8610的情况,通过重写 /actuator/httptrace端点直接在 jackson(json框架)处理对象序列化前,直接处理 timestamp字段,解决 timestamp转化问题。

相关处理如下:

  • 1、自定义 CustomHttpTrace替换 HttpTrace,两者区别只有字段 timestampCustomHttpTrace.java
    image.png
  • 2、自定义 CustomHttpTraceEndpoint替换 HttpTraceEndpoint,两者的区分在于数据结构中的 timestamp 字段CustomHttpTraceEndpoint.java
    image.png
  • 3、停用 actuator 默认 HttpTraceEndpoint 的自动配置类,
    image.png

    四、生产中的安全问题

Spring Boot Actuator提供了对应应用的端点监控及访问信息,如:生成配置、日志、线程、Http访问trace 等。

但同时也带来了安全隐患,如果处理不当,将会使得应用信息完全暴露在互联网中。

如:在未对配置信息进行加密的情况下,可以直接通过 /actuator/env拿到应用的上下文配置信息,如:数据库密码、各种账号密钥信息等。

如:可以通过 /actuator/trace拿到HTTP请求信息,即可能拿到请求头中的 token,从而通过 token 模拟用户请求,造成用户数据泄露等问题。

所以在生成中,需要按需开放 Actuator Endpoint ,同时需要引入安全框架,间对外开放 Actuator 保护起来。

4.1、Client 端安全框架的引入

如果项目中本身就是使用的 Security进行的身份认证,可以不再引入相关依赖,否则可以直接引入 spring-security组件。 除此之外也可以自定义安全认证,本质上就是针对API的授权认证处理。

  • step1、引入 spring-security组件

    • 基于 配置设置用户信息,可以基于内存的配置,也可以基于DB存储等,以 application.properties为例:
      image.png
    • 配置对 ActuatorAPI 的访问控制,例如:
      具体配置根据项目而定:
      image.png
  • step2、application.properties追加配置

    • 基于 http 信息上报方式的配置
      image.png
    • 基于 Eureka 信息上报方式的配置
      image.png

      4.2、Server 端不变