Spring Boot Actuator
提供了对单个
Spring Boot
应⽤的监控,信息包含应⽤状态、内存、线程、堆栈等,⽐
较全⾯的监控了
Spring Boot
应⽤的整个⽣命周期。
但是这样监控也有⼀些问题:第⼀,所有的监控都需要调⽤固定的接⼝来查看,如果全⾯查看应⽤状态需要
调⽤很多接⼝,并且接⼝返回的
JSON
信息不⽅便运营⼈员理解;第⼆,如果
Spring Boot
应⽤集群⾮常
⼤,每个应⽤都需要调⽤不同的接⼝来查看监控信息,操作⾮常繁琐低效。在这样的背景下,就诞⽣了另外
⼀个开源软件:
Spring Boot Admin
。
什么是 Spring Boot Admin
Spring Boot Admin
是⼀个管理和监控
Spring Boot
应⽤程序的开源软件,每个应⽤都认为是⼀个客户端,通
过
HTTP
或者使⽤
Eureka
注册到
admin server
中进⾏展示,
Spring Boot Admin UI
部分使⽤
Vue.js
将数据
展示在前端。
Spring Boot Admin
是⼀个针对
Spring Boot
的
Actuator
接⼝进⾏
UI
美化封装的监控⼯具,它可以在列表中
浏览所有被监控
spring-boot
项⽬的基本信息、详细的
Health
信息、内存信息、
JVM
信息、垃圾回收信息、
各种配置信息(⽐如数据源、缓存列表和命中率)等,还可以直接修改
logger
的
level
。
值得注意的是
Spring Boot Admin
并不是
Spring Boot
官⽅出品的开源软件,但是其软件质量和使⽤⼴泛度
都⾮常的⾼,并且
Spring Boot Admin
会及时随着
Spring Boot
的更新⽽更新,当
Spring Boot
推出
2.X
版本
时
Spring Boot Admin
也及时进⾏了更新。
Spring Boot Admin 2.x
不仅是跟着⽀持了
Spring Boot 2.x
,还在
1.x
的基础上进⾏了⼤量的更新和优化
:
- 重新规划了项⽬依赖包,让项⽬中更⽅便的集成 Spring Boot Admin
- 1.x 前端使⽤了 Angular.js,2.x 使⽤ Vue 对界⾯进⾏了重写,界⾯美观度提升幅度⾮常⾼
- 提供了⽀持 Spring Cloud 的组件
- 其他更新,具体参考:Changes with 2.x
Spring Boot Admin
分为服务端和客户端,服务端其实就是⼀个监控后台⽤来汇总展示所有的监控信息,客户
端就是我们的应⽤,使⽤时需要先启动服务端,在启动客户端的时候打开
Actuator
的接⼝,并指向服务端的
地址,这样服务端会定时读取相关信息以达到监控的⽬的。
接下来演示如何使⽤
Spring Boot Admin
对
Spring Boot
应⽤进⾏监控。
监控单体应⽤
先给⼤家展示如何使⽤
Spring Boot Admin
监控单个
Spring Boot
应⽤。
Admin Server 端
项⽬依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.x
下只需要添加此⼀个包即可,其他组件会⾃动依赖添加。
配置⽂件
server.port=8000
服务端设置端⼝为:
8000
。
启动类
@EnableAdminServer
@SpringBootApplication
public class AdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(AdminServerApplication.class, args);
}
}
完成上⾯三步之后,启动服务端,访问⽹址
http://localhost:8000
可以看到以下界⾯:
因为刚启动没有应⽤,因此显示:
No applications registered.
,同时根据上图也可以看出
applications
⻚⾯
会展示项⽬的应⽤数、实例数和状态三个信息。
接下来我们构建⼀个客户端,并注册到服务端。
Admin Client 端
项⽬依赖
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
添加
spring-boot-starter-web
是为了使应⽤处于启动状态,
spring-boot-admin-starter-client
会⾃动添加
Actuator
相关依赖。
配置⽂件
server.port=8001
spring.application.name=Admin Client
spring.boot.admin.client.url=http://localhost:8000
management.endpoints.web.exposure.include=*
- spring.boot.admin.client.url 配置 Admin Server 的地址
- management.endpoints.web.exposure.include=* 打开客户端 Actuator 的监控
启动类
@SpringBootApplication
public class AdminClientApplication {
public static void main(String[] args) {
SpringApplication.run(AdminClientApplication.class, args);
}
}
配置完成之后,启动
Client
端,
Admin
服务端会⾃动检查到客户端的变化,并展示其应⽤:
⻚⾯会展示被监控的服务列表,点击项⽬名称会进⼊此应⽤的详细监控信息:
通过上图可以看出,
Spring Boot Admin
以图形化的形式展示了应⽤的各项信息,这些信息⼤多都来⾃于
Spring Boot Actuator
提供的接⼝。利⽤图形化的形式很容易看到应⽤的各项参数变化,甚⾄有些⻚⾯还可以
进⾏⼀些操作,⽐如改变打印⽇志的级别等。
点击journal页面可以看到应用状态变化的历史过程:
点击第⼀个菜单
wallboard
可以以更形象的⽅式查看应⽤数量启动的时间等。
监控微服务
如果我们使⽤的是单个
Spring Boot
应⽤,就需要在每⼀个被监控的应⽤中配置
Admin Server
的地址信息;
如果应⽤都注册在
Eureka
中就不需要再对每个应⽤进⾏配置,
Spring Boot Admin
会⾃动从注册中⼼抓取应
⽤的相关信息。
如果使⽤了
Spring Cloud
的服务发现功能,就不需要再单独添加
Admin Client
客户端,仅仅需要
Spring
Boot Server
,其他内容会⾃动进⾏配置。
接下来以
Eureka
作为服务发现的示例来进⾏演示,实际上也可以使⽤
Consul
或者
Zookeeper
。
(
1
)服务端和客户端添加
spring-cloud-starter-eureka
到包依赖中
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(
2
)启动类添加注解
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
@EnableAdminServer
public class SpringBootAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminApplication.class, args);
}
@Configuration
public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapt
er {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll()
.and().csrf().disable();
}
}
}
使⽤类
SecurityPermitAllConfifig
关闭了安全验证。
(
3
)在客户端中配置服务发现的地址
eureka:
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /actuator/health
metadata-map:
startup: ${random.int} #needed to trigger info and endpoint update after
restart
client:
registryFetchIntervalSeconds: 5
serviceUrl:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
Spring Cloud
提供了示例代码可以参考这⾥:
spring-boot-admin-sample-eureka
。
GitChat
重启启动服务端和客户端之后,访问服务端的相关地址就可以看到监控⻚⾯了。
安全控制
Spring Boot Admin
后台有很多的敏感信息和操作,如果公司不做权限控制可能会影响到公司系统的安全性。
Spring Boot Admin
也考虑到了这个因素,可以利⽤前⾯的
Spring Security
做安全访问控制,在
spring-boot
admin-server
上进⾏改造。
(
1
)添加
Spring Boot Security
依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
(
2
)添加安全访问控制
和前⾯的
Security
配置⼀样,给项⽬添加访问控制。
@Configuration
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 {
// @formatter:off
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRe
questAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(success
Handler).and()
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
- antMatchers(adminContextPath + "/assets/**").permitAll() 所有静态内容不做安全验证
- anyRequest().authenticated() 其他请求均需要验证
- formLogin() 配置登录
- logout() 配置登出
- httpBasic() ⽀持 HTTP,引导 Spring Boot Admin 客户端注册
- csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 打开跨站点请求保护 Cookies
- adminContextPath + "/instances" 取消跨站点请求保护 "/instances",⽅便 Admin 客户端注册
- adminContextPath + "/actuator/**" 取消跨站点请求保护 "/actuator/**",可以让 Admin 监控到 Actuator 的相关接⼝
然后可以给
security
设置⼀个⽤户名和密码:
spring.security.user.name=admin
spring.security.user.password=admin
配置完成之后重启
Admin Server
端,访问⽹址
http://localhost:8000
就会发现需要⼀个登录的⽤户名和密码
了。
使⽤刚才设置的⽤户名和密码登录之后,发现注册到
Server
端的服务数成为
0
了,这是客户端统⼀也需要配
置帐户名和密码信息。
spring.security.user.name=admin
spring.security.user.password=admin
配置完成之后重新启动,在服务端就⼜可以查看监控到的应⽤了。
其他⽅式
如果
Actuator
的端⼝被使⽤
HTTP
认证保护,那么
Spring Boot Admin Server
访问的时候需要凭证信息,这
时候可以使⽤
metadata
的⽅式对账户和密码进⾏配置。
直接使⽤客户端注册的⽅式:
spring.boot.admin.client:
url: http://localhost:8080
instance:
metadata:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
使⽤
Eureka
进⾏注册的⽅式:
eureka:
instance:
metadata-map:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
Eureka
中的
metadataMap
是专⻔⽤来存放⼀些⾃定义的数据,当注册中⼼或者其他服务需要此服务的某些
配置时可以在
metadataMap
⾥取。实际上,每个
instance
都有各⾃的
metadataMap
,
map
中存放着需要⽤
到的属性。例如,上⾯配置中的
eureka.instance.metadata-map.user.name
,当这个服务成功注册到
Eureka
上,
Spring Boot Admin
就会拿到这个
instance
,进⽽拿到
metadataMap
⾥的属性,然后放⼊请求头,向此
服务发送请求,访问此服务的
Actuator
开放的端点。
邮件告警
Spring Boot Admin
将微服务中所有应⽤信息在后台进⾏了展示,⾮常⽅便我们对微服务整体的监控和治理。
但是我们的运营⼈员也不可能⼀天
24
⼩时盯着监控后台,因此如果服务有异常的时候,有对应的邮件告警
就太好了,其实
Spring Boot Admin
也给出了⽀持。
我们对上⾯的示例项⽬
spring-boot-admin-server
进⾏改造。
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
增加了邮件发送的
starter
包。
配置⽂件
spring.mail.host=smtp.qq.com
[email protected]
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
[email protected]
[email protected]
在配置⽂件中添加邮件发送相关信息:邮件的发送者、接受者、协议、移动授权码等。
配置完成后,重新启动项⽬
spring-boot-admin-server
,这样
Admin Server
就具备了邮件告警的功能,默认
GitChat
情况下
Admin Server
对
Eureka
中的服务上下线都进⾏了监控,当服务上下线的时候我们就会收到如下邮
件:
当然这只是最基本的邮件监控,在实际的使⽤过程中,需要根据情况对邮件告警内容进⾏⾃定义,⽐如监控
堆内存的使⽤情况,当到达⼀定⽐例的时候进⾏告警等。
总结
Spring Boot Admin
解决了我们对⼤规模
Spring Boot
应⽤监控的需求,
Spring Boot Admin
充分利⽤了
Actuator
开放的相关接⼝,采⽤优秀的图形界⾯将这些信息进⾏了展示,⽅便我们更加直观的查看集群中应
⽤的状态。
Spring Boot Admin
不仅可以监控单个
Spring Boot
应⽤,也可以结合
Spring Cloud
监控注册到
服务中⼼的所有应⽤状态,再结合报警系统的使⽤就可以随时感知到应⽤的状态变化。在实际⼯作中
Spring
Boot Admin
是我们在后期运营中频繁⽤到的⼀个组件,应该作为重点关注。