SpringBoot系列——admin服务监控
  前⾔
  springboot项⽬部署起来后,如何实时监控项⽬的运⾏状况呢?本⽂记录使⽤springboot-admin对服务进⾏监控。
  ⼯程结构
  服务端
  server服务端
  客户端
  client客户端
  服务端、客户端都是独⽴的web项⽬,服务端是监控程序,客户端是被监控的程序,本⽂只测试了⼀个客户端接⼊
  代码编写
  服务端
  server服务端引⼊相关依赖
  2.2.0后admin的管理页⾯⽀持中⽂,因此我们引⼊此版本(parent不再是引⼊我们的⽗⼯程pom了,直接引⼊springboot的2.2.0)        <!-- 引⼊admin相关依赖 2.2.0页⾯⽀持中⽂显⽰,需要springboot 2.2.0 -->
<dependency>
<groupId&decentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.0</version>
</dependency>
  为了安全性,引⼊security
<!--springboot security 安全相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
  解决控制台报错,移除tomcat,改⽤jetty
<!--
报错:java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
解决:移除tomcat,换成jetty
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
  监控系统,直接配置账号、密码,不⽤搞那么⿇烦接⼊数据库
#配置⼀个账号和密码
spring.security.user.name=admin
spring.security.user.password=123456
  做好security配置
/**
* Security安全配置
*/
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
/
/项⽬应⽤路径
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = ContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
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()
//开启http basic⽀持,admin-client注册时需要使⽤
.httpBasic().and()
.csrf()
/
/开启基于cookie的csrf保护
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
//忽略这些路径的csrf保护以便admin-client注册
.ignoringAntMatchers(
adminContextPath + "/instances",
adminContextPath + "/actuator/**"
);
}
}
  客户端是要暴露actuator的web端⼝的,为了安全,客户端只允许服务端请求actuator的web接⼝,为了⽅便客户端区分请求来源,我们在请求头注⼊⾃定义参数
/**
* 注⼊额外的请求头,⽅便客户端区分请求来源
*/
@Component
public class HttpHeadersProviderConfig implements HttpHeadersProvider {
@Value("${server.port}")
private String port;
@Override
public HttpHeaders getHeaders(Instance instance) {
HttpHeaders httpHeaders = new HttpHeaders();
//设置约定好的请求头参数
httpHeaders.add("spring-boot-admin-service", port);
return httpHeaders;
}
}
  我们不可能整天上系统看监控数据,做好⾃定义通知,当实例状态发⽣改变,及时通知(发邮件、企业、钉钉都可以,⾃⼰实现)
/**
* ⾃定义通知
* 继承 AbstractStatusChangeNotifier 类,实现了 doNotify ⽅法,
* 当应⽤状态改变的时候会回调 doNotify ⽅法。
*/
@Component
public class CustomNotifierConfig extends AbstractStatusChangeNotifier {
public CustomNotifierConfig(InstanceRepository repository) {
super(repository);
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
if (event instanceof InstanceStatusChangedEvent) {
System.out.println("实例名称:"+Registration().getName());
System.out.println("实例服务地址:"+Registration().getServiceUrl());                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
switch (status) {
case "DOWN":
System.out.println("健康检查没通过!");
break;
case "OFFLINE":
System.out.println("服务离线!");
break;
case "UP":
System.out.println("服务上线!");
break;
case "UNKNOWN":
System.out.println("服务未知异常!");
break;
default:
System.out.println(status);
break;
}
}
});
}
}
  最后在启动打上@EnableAdminServer注解,开启服务监控
@EnableAdminServer//开启AdminServer功能
@SpringBootApplication
public class SpringBootAdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminServerApplication.class, args);
}
/**
* 启动成功
*/
@Bean
public ApplicationRunner applicationRunner() {
return applicationArguments -> {
System.out.println("启动成功!");
};
}
}
  客户端
  服务端引⼊了2.2.0版本的依赖,因此客户端也要引⼊2.2.0依赖
<!-- 引⼊admin相关依赖 -->
<dependency>
<groupId&decentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.2.0</version>
</dependency>
  在配置⽂件中,开启端⼝、配置admin的server地址,以及账号、密码
#启⽤端点,默认情况下,除shutdown以外的所有端点均已启⽤
#显⽰db、redis、rabbti连接情况等
#公开所有端点web接⼝
#admin-server地址,以及登录账号、密码
spring.boot.admin.client.port=10010
spring.boot.admin.client.url=localhost:${spring.boot.admin.client.port}
spring.boot.admin.client.username=admin
spring.boot.admin.client.password=123456
  为了⽅便测试其他东西
<!--添加springdata-cache依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--添加MySQL驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
  同时创建测试接⼝、定时器、cache缓存、异步任务,就是为了看服务端能否监控到
  客户端是要暴露actuator的web端⼝的,为了安全,客户端只允许服务端请求actuator的web接⼝(通过约定好的请求头来判断)/**
* 针对actuator接⼝做安全限制,只允许服务端调⽤
*/
@WebFilter
@ServletComponentScan
@Component
public class ActuatorFilter implements Filter {
@Value("${spring.boot.admin.client.port}")
private String adminServicePort;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
//判断约定好的请求头参数
if (RequestURI().contains("/actuator") && !adminServicePort.Header("spring-boot-admin-service"))){
throw new RuntimeException("抱歉,你⽆权限访问,Actuator端⼝受保护! Sorry, you have no permission to access it,Actuator port protected!");
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
  效果演⽰
  安全配置⽣效
  ⾸先先看安全配置都⽣效了没有
  访问服务端,需要登录
  登录上去,客户端已经注册成功
  正常监控客户端中...
  浏览器直接访问客户端的actuator接⼝,直接抛出异常
  其他接⼝正常访问
  ⾃定义通知
  注:客户端⾸次在服务端注册,并没有触发⾃定义通知
  再看下⾃定义通知
  停掉客户端服务、重启启动客户端,触发服务端⾃定义通知
  具体监控项
  具体客户端的监控⾸页,有我们在客户端写的info信息、磁盘监控、堆、⾮堆内存监控、进程、线程监控、垃圾回收监控#添加描述
info.describe=SpringBootAdmin,Test Client Service!
info.author=huanzi-qch
info.version=1.0.0
  计划任务这⾥可以看到我们配置的定时器
  web映射可以看到所有的web接⼝
springboot中文  http跟踪,可以查看具体请求的响应情况
  缓存菜单,可以看到我们使⽤到的缓存空间
  还可以下载jvm dump⽂件
  其他就不⼀⼀列举,⾃⼰把项⽬跑起来再看

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。