课程名称:Spring Cloud / Alibaba 微服务架构实战
课程章节:第5章-SpringBoot Admin 微服务应用监控
课程讲师:张勤一
课程内容:
1. 搭建 SpringBoot Admin 监控服务器
1.1 认识SpringBoot Actuator
-
Actuator Endpoints(端点)
-
Endpoints是Actuator的核心部分,它用来监视应用程序及交互;SpringBoot Actuator内置了很多Endpoints,并支持扩展。
-
SpringBoot Actuator提供的原生端点有三类:
-
应用配置类:自动配置信息,SpringBean信息,yml文件信息,环境信息等等。
-
度量指标类:主要是运行期间的动态信息,例如堆栈,健康指标,metrics信息等等。
-
操作控制类:主要是指shutdown,用户可以发送一个请求将应用的监控功能关闭。
-
-
1.2 搭建SpringBoot Admin 监控服务器
- 引入SpringBoot Admin Starter 自动配置依赖
<!-- SpringBoot Admin -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.0</version>
</dependency>
- 添加启动类注解:@EnableAdminServer
@EnableAdminServer
@SpringBootApplication
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
-
应用注册到SpringBoot Admin Server的两种方式
-
被监控和管理的应用程序,使用SpringBoot Admin Client库,通过HTTP调用注册到SpringBoot Admin Server中。
-
被监控和管理的应用程序都注册到SpringCloud集成的注册中心,SpringBoot Admin Server通过注册中心获取被监控和管理的应用程序。
-
server:
port: 7001
servlet:
context-path: /e-commerce-admin
spring:
application:
name: e-commerce-admin
security:
user:
name: imooc-qinyi
password: 88888888
cloud:
nacos:
discovery:
enabled: true
server-addr: IP:8848
namespace: c7b708c9-0e4b-4cfa-9637-e794dfe7063e
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
user.name: imooc-qinyi
user.password: 88888888
thymeleaf:
check-template: false
check-template-location: false
# 被监控的应用状态变更为 DOWN、OFFLINE、UNKNOWN 时, 会自动发出告警: 实例的状态、原因、实例地址等信息
# 需要在 pom.xml 文件中添加 spring-boot-starter-mail 依赖
# 配置发送告警的邮箱服务器
# 但是, 这个要能连接上, 否则会报错
# mail:
# host: qinyi.imooc.com
# username: qinyi@imooc.com
# password: QinyiZhang
# default-encoding: UTF-8
# 监控告警通知
# boot:
# admin:
# notify:
# mail:
# from: ${spring.mail.username}
# to: qinyi@imooc.com
# cc: qinyi@imooc.com
# 暴露端点
management:
endpoints:
web:
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 *, 可以开放所有端点
endpoint:
health:
show-details: always
2. 监控中心服务器添加安全访问控制
- 引入安全认证框架
<!-- 开启登录认证功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- 添加配置信息
spring:
application:
name: e-commerce-admin
#认证账户信息
security:
user:
name: imooc-qinyi
password: 88888888
cloud:
nacos:
discovery:
enabled: true
server-addr: IP:8848
namespace: c7b708c9-0e4b-4cfa-9637-e794dfe7063e
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
user.name: imooc-qinyi
user.password: 88888888
- 编写配置类,方便其他服务可以注册到SpringBoot Admin Server中
package com.imooc.ecommerce.conf;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
/**
* <h1>配置安全认证, 以便其他的微服务可以注册</h1>
* 参考 Spring 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 {
SavedRequestAwareAuthenticationSuccessHandler successHandler =
new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
// 1. 配置所有的静态资源和登录页可以公开访问
.antMatchers(adminContextPath + "/assets/**").permitAll()
.antMatchers(adminContextPath + "/login").permitAll()
// 2. 其他请求, 必须要经过认证
.anyRequest().authenticated()
.and()
// 3. 配置登录和登出路径
.formLogin().loginPage(adminContextPath + "/login")
.successHandler(successHandler)
.and()
.logout().logoutUrl(adminContextPath + "/logout")
.and()
// 4. 开启 http basic 支持, 其他的服务模块注册时需要使用
.httpBasic()
.and()
// 5. 开启基于 cookie 的 csrf 保护
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
// 6. 忽略这些路径的 csrf 保护以便其他的模块可以实现注册
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
-
自定义监控报警
-
通过邮箱方式
-
钉钉,企业微信通知等方式
模拟
-
package com.imooc.ecommerce.notifier;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* 自定义报警
*/
@Slf4j
@Component
public class SpringBootApplicationNotifier extends AbstractEventNotifier {
public SpringBootApplicationNotifier(InstanceRepository repository) {
super(repository);
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
//编写具体的业务逻辑
if (event instanceof InstanceStatusChangedEvent){
log.info("Instance Status Changes: [{}], [{}], [{}]",
instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());
}else {
log.info("Instance Info: [{}], [{}], [{}]",
instance.getRegistration().getName(), event.getInstance(),
event.getType());
}
});
}
}