之前学习了Spring Boot Actuator的特性,它能够是开发者很便捷的监控系统的各种指标,但是有一个很大的问题 — 不够直观。今天来学习下Spring Boot Admin。Spring Boot Admin 是一个免费的开源社区项目,用于监控、管理Spring Boot 应用系统。Spring Boot Admin的架构采用客户端 - 服务器模式,客户端通过HTTP协议周期性的向服务端上报自身服务状态,实现监控管理的目的。Spring Boot Admin提供以下特性:
首先需要启动Spring Boot Admin 服务端程序。为此,只需要启动一个简单的Spring Boot项目即可,由于Spring Boot Admin 服务端能够作为servlet、webflux应用运行,因此Spring Boot 应用只需要添加对应的Spring Boot Starter,
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>2.7.5version>
dependency>
使用maven脚本下载依赖
mvn clean install -Dmaven.test.skip=true
接下来只需要在启动类上增加**@EnableAdminServer**注解即可
@SpringBootApplication
@EnableAdminServer
public class SpringbootStudyApplication {
public static void main(String[] args) {
ConfigurableApplicationContext app = SpringApplication.run(SpringbootStudyApplication.class, args);
DatabaseProperties bean = app.getBean(DatabaseProperties.class);
ServerProperties server = app.getBean(ServerProperties.class);
}
}
启动应用程序,在浏览器访问 http://localhost:8090/applications (application.properties文件中配置的端口为: server.port=8090)
由于目前尚未注册客户端,因此没有任何数据展示出来。
向Spring Boot Admin 服务端注册应用程序,跟服务端启动类似,普通的Spring Boot 应用程序也只需要引入Spring Boot Admin Client starter 依赖即可。
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-clientartifactId>
<version>2.7.5version>
dependency>
启动Spring Boot Admin 客户端需要在Spring Boot application.properties配置文件中,添加以下配置:
spring.boot.admin.client.url=http://localhost:8090
management.endpoints.web.exposure.include=*
# 设置服务名称 方便识别
spring.application.name=Spring-Boot-Admin-Client
注意:启动Spring Boot Admin Client 只需要做以上两步即可,不需要在程序添加额外的注解
运行客户端后,重新打开服务端地址,可以看到客户端已经注册上了
客户端多个节点集群部署时,Spring Boot Admin 根据服务名称自动进行分组,因此从Spring Boot Admin UI界面可以很清晰的看出实例的个数。使用IDEA工具或以下命令将客户端启动多次
# 第一次启动
java -jar target/spring-boot-admin-client-0.0.1-SNAPSHOT.jar --server.port=8081
# 第二次启动
java -jar target/spring-boot-admin-client-0.0.1-SNAPSHOT.jar --server.port=8082
从上面的截图中,可以一目了然的看出服务名称、实例个数、运行时长。
Spring Boot Admin 也支持Spring Cloud 微服务体系中服务发现、注册机制,客户端注册流程甚至不需要单独引入Client 依赖,这里就不做过多的介绍,请参考官方文档。
现在来介绍下Spring Boot Admin 服务端、客户端相关的配置参数,这对开发者进行定制服务、参数调优很有帮助
Spring Boot Admin 客户端向服务端注册,并周期性的发送HTTP POST请求来确保客户端系统处于健康状态。
参数名称 | 参数描述 | 默认值 |
---|---|---|
spring.boot.admin.client.enabled | 启动 Spring Boot Admin 客户端. | true |
spring.boot.admin.client.url | 注册Spring Boot Admin 服务端的地址,多个地址之间用逗号分隔。必填属性 | |
spring.boot.admin.client.api-path | 向服务端注册 Endpoint 的Http URI | "instances" |
spring.boot.admin.client.username spring.boot.admin.client.password | Spring Boot Admin 启用认证时,账号、密码信息 | |
spring.boot.admin.client.period | 重复注册时间间隔,单位毫秒 | 10,000 |
spring.boot.admin.client.connect-timeout | 注册连接超时时间,单位毫秒 | 5,000 |
spring.boot.admin.client.read-timeout | 注册读取超时时间,单位毫秒 | 5,000 |
spring.boot.admin.client.auto-registration | 设置为true, 应用自动开启定时任务,向服务端法搜是那个注册信息 | true |
spring.boot.admin.client.auto-deregistration | Spring Boot Admin 上下文信息关闭时,切换自动注销设置。如未设置该值,当检测到服务端处于运行状态,则该功能处于活跃状态 | null |
spring.boot.admin.client.register-once | 如果设置为true,客户端将只注册一个管理服务器(按照spring.boot.admin.extence.url定义的顺序);如果该管理服务器停机,将自动向下一个管理服务器注册。如果为false,将在所有管理服务器上注册 | true |
spring.boot.admin.client.instance.health-url | 健康检查注册URL,可以重写为任意一个课访问的URL,但必须唯一 | Guessed based on management-url and endpoints.health.id . |
spring.boot.admin.client.instance.management-base-url | 用于计算、管理注册的基础URL,conext 在运行时指定,并附加基础URL | Guessed based on management.port , service-url and server.servlet-path . |
spring.boot.admin.client.instance.management-url | 注册URL,可以被覆盖为任意可访问的URL | Guessed based on management-base-url and management.context-path . |
spring.boot.admin.client.instance.service-base-url | 用于计算服务注册的基础URL,context在运行时指定,并附加基础URL。在Cloudfoundary环境中,可以切换为: spring.boot.admin.client.instance.service-base-url=https://${vcap.application.uris[0]} | Guessed based on hostname, server.port . |
spring.boot.admin.client.instance.service-url | 服务注册URL,可以被覆盖为任意可访问的URL | Guessed based on service-base-url and server.context-path . |
spring.boot.admin.client.instance.service-path | 注册的服务路径,可以被覆盖为任意可访问的PATH | / |
spring.boot.admin.client.instance.name | 注册服务名 | ${spring.application.name} if set, "spring-boot-application" otherwise. |
spring.boot.admin.client.instance.prefer-ip | 使用IP地址进行服务注册。可以通过参数指定server.address/ management.address. 否则默认使用IP地址 | false |
spring.boot.admin.client.instance.metadata.* | 实例内部以键值对存储的元数据 | |
spring.boot.admin.client.instance.metadata.tags.* | 实例内部以键值对存储的Tag元数据 |
Property name | Description | Default value |
---|---|---|
spring.boot.admin.context-path | 服务端静态资源的URI访问的 上线文前缀 | |
spring.boot.admin.monitor.status-interval | 客户端实例状态检查时间间隔 | 10,000ms |
spring.boot.admin.monitor.status-lifetime | 状态生命周期. 上次状态未过期,状态不变更 | 10,000ms |
spring.boot.admin.monitor.info-interval | 客户端实例信息检查时间间隔 | 1m |
spring.boot.admin.monitor.info-lifetime | 信息的生命周期。只要最后一条信息未过期,信息将不会更新 | 1m |
spring.boot.admin.monitor.default-timeout | 默认请求超时时间,可使用spring.boot.admin.monitor.timeout.*`进行覆盖 | 10,000 |
spring.boot.admin.monitor.timeout.* | Endpoints指定的超时时间,每一个Endpoint以endpointid、timeout 进行键值对存储 | |
spring.boot.admin.monitor.default-retries | 失败请求重试次数,设置请求(PUT , POST , PATCH , DELETE ) 不可重试.可使用spring.boot.admin.monitor.retries.*进行参数覆盖 | 0 |
spring.boot.admin.monitor.retries.* | Endpoints重试次数,每一个Endpoint以键值对的形式存储重试次数 | |
spring.boot.admin.metadata-keys-to-sanitize | 通过正则表达式匹配元数据的值. | ".**password$", ".\*secret$", ".\*key$", ".\*token$", ".\*credentials.**", ".*vcap_services$" |
spring.boot.admin.probed-endpoints | 对于Spring Boot 1.x客户端应用程序,SBA使用OPTIONS请求探测指定端点。如果路径与id不同,可以将其指定为id:path(例如health:ping) | "health", "env", "metrics", "httptrace:trace", "threaddump:dump", "jolokia", "info", "logfile", "refresh", "flyway", "liquibase", "heapdump", "loggers", "auditevents" |
spring.boot.admin.instance-auth.enabled | 从Spring 配置属性中获取认证信息 | true |
spring.boot.admin.instance-auth.default-user-name | 注册服务时,默认认证账号信息. spring.boot.admin.instance-auth.enabled 必须设置为true. | null |
spring.boot.admin.instance-auth.default-password | 注册服务时,默认认证密码信息. spring.boot.admin.instance-auth.enabled` 必须设置为true. | null |
spring.boot.admin.instance-auth.service-map.*.user-name | 注册服务时,指定账号信息. spring.boot.admin.instance-auth.enabled` 必须设置为true. | |
spring.boot.admin.instance-auth.service-map.*.user-password | 注册服务时,指定密码信息. spring.boot.admin.instance-auth.enabled` 必须设置为true… | |
spring.boot.admin.instance-proxy.ignored-headers | 向客户端发送请求时,不携带header 请求头 | "Cookie", "Set-Cookie", "Authorization" |
spring.boot.admin.ui.public-url | 构建UI方位URL的基础URL | If running behind a reverse proxy (using path rewriting) this can be used to make correct self references. If the host/port is omitted it will be inferred from the request. |
spring.boot.admin.ui.brand | 导航栏中显示的品牌。 | "Spring Boot Admin" |
spring.boot.admin.ui.title | 页面展示Title信息 | "Spring Boot Admin" |
spring.boot.admin.ui.login-icon | 登录页面Icon图标. | "assets/img/icon-spring-boot-admin.svg" |
spring.boot.admin.ui.favicon | 默认桌面通知icon | "assets/img/favicon.png" |
spring.boot.admin.ui.favicon-danger | 服务下线,桌面通知icon | "assets/img/favicon-danger.png" |
spring.boot.admin.ui.remember-me-enabled | 切换以显示/隐藏登录页面上的“记住我”复选框 | true |
spring.boot.admin.ui.poll-timer.cache | 设置拉取缓存数据的轮询时间(毫秒) | 2500 |
spring.boot.admin.ui.poll-timer.datasource | 设置拉取数据库数据的轮询时间(毫秒) | 2500 |
spring.boot.admin.ui.poll-timer.gc | 设置获取GC数据的轮询时间(毫秒) | 2500 |
spring.boot.admin.ui.poll-timer.process | 设置获取进程数据的轮询时间(毫秒 | 2500 |
spring.boot.admin.ui.poll-timer.memory | 设置获取内存数据的轮询时间(毫秒 | 2500 |
spring.boot.admin.ui.poll-timer.threads | 设置获取线程数据的轮询时间(毫秒 | 2500 |
有多种方式解决分布式web应用程序中的身份验证、授权问题。Spring Boot Admin没有提供默认的方式。可以通过集成Spring Security,让Spring Boot Admin UI管理界面提供了简单的登录、注销功能。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
<version>2.7.5version>
dependency>
# 在application.properties文件新增以下配置
spring.security.user.name=admin
spring.security.user.password=admin
@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final AdminServerProperties adminServer;
private final SecurityProperties security;
public SecuritySecureConfig(AdminServerProperties adminServer, SecurityProperties security) {
this.adminServer = adminServer;
this.security = security;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeRequests(
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll()
.antMatchers(this.adminServer.path("/actuator/info")).permitAll()
.antMatchers(this.adminServer.path("/actuator/health")).permitAll()
.antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated()
).formLogin(
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and()
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults())
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminServer.path("/instances"),
HttpMethod.POST.toString()),
new AntPathRequestMatcher(this.adminServer.path("/instances/*"),
HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))
))
.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
}
// Required to provide UserDetailsService for "remember functionality"
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(security.getUser().getName())
.password("{noop}" + security.getUser().getPassword()).roles("USER");
}
}
Spring Boot Admin 客户端设置比较简单,只需要在注册信息携带账号、密码即可
# 在application.properties 配置文件中添加
spring.boot.admin.client.username=admin
spring.boot.admin.client.password=admin
当服务状态变更时,Spring Boot Admin默认支持多种方式进行消息通知,让系统人员第一时间进行处理,下面以发送EMAIL为例:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
<version>2.7.5version>
dependency>
#授权码
spring.mail.password=TGLDQKDBEDVSUPWZ
spring.mail.port=25
spring.mail.properties.mail.smtp.auth=true
spring.boot.admin.notify.mail.from=xxx@163.com
spring.boot.admin.notify.mail.to=xxx@163.com
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
当服务端检测到客户端状态从正常到下线时,则触发邮件报警通知:
spring.boot.admin.notify.mail.ignore-changes="UNKNOWN:UP"
Spring Boot Admin 可以通过设置以上参数,忽略指定的状态,从而不触发消息报警机制。以上配置表示客户端上线不发送邮件通知.
Spring Boot Admin 定义的服务状态在源码中有体现:
public final class StatusInfo implements Serializable {
public static final String STATUS_UNKNOWN = "UNKNOWN";
public static final String STATUS_OUT_OF_SERVICE = "OUT_OF_SERVICE";
public static final String STATUS_UP = "UP";
public static final String STATUS_DOWN = "DOWN";
public static final String STATUS_OFFLINE = "OFFLINE";
public static final String STATUS_RESTRICTED = "RESTRICTED";
//...
}
Spring Boot Admin 也预留了接口给开发者自定义消息通知,如国内企业比较流行的钉钉、企业微信通知
public class CustomNotifier extends AbstractEventNotifier {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingNotifier.class);
public CustomNotifier(InstanceRepository repository) {
super(repository);
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
if (event instanceof InstanceStatusChangedEvent) {
LOGGER.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());
}
else {
LOGGER.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
event.getType());
}
});
}
}
参考:
https://blog.csdn.net/caychen/article/details/82887926
https://blog.csdn.net/weixin_37610397/article/details/104064472