【Springboot】SpringBoot-Admin 服务监控+告警通知
SpringBoot-Admin 服务监控
简单介绍
Spring Boot Actuator 是 Spring Boot 自带的一个功能模块,
提供了一组已经开箱即用的生产环境下常用的特性和服务,比如应用程序的健康检查、信息暴露、度量收集、日志记录等。
在实际项目中,Actuator 可以帮助我们快速了解应用程序的运行状态和性能瓶颈。
整合SpringBoot-Admin监控,Spring Boot Admin 就是将 Spring Boot Actuator中提供的endpoint信息可视化展示。
环境
Springboot: 2.1.1.RELEASE
注意:不同的SpringBoot版本,所用到的依赖会不一致。本版本亲测可用哦。
服务端简单搭建
核心依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-login</artifactId>
<version>1.5.7</version>
</dependency>
启动类
@EnableAdminServer //开启admin服务端
@SpringBootApplication
public class BootAdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(BootAdminServerApplication.class, args);
}
}
配置文件
server:
port: 8001
servlet:
context-path: /admin-server
spring:
application:
name: admin-server
启动服务后,访问:http://localhost:8001/admin-server

安全认证
核心依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
SecuritySecureConfig 拦截器Code
@EnableWebSecurity
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServer) {
this.adminContextPath = adminServer.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
.antMatchers(adminContextPath + "/login",
adminContextPath + "/assets/**",
adminContextPath + "/manage/**",
adminContextPath + "/actuator/**",
adminContextPath + "/login.html"
).permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler)
.and()
.logout().logoutUrl(adminContextPath + "/logout")
.and()
.httpBasic()
.and()
.csrf().disable();
}
}
修改配置
新增以下配置
spring:
security:
user:
name: admin
password: admin
启动服务后,访问:http://localhost:8001/admin-server

输入用户名,密码即可。
客户端
核心依赖
<!--加入spring-boot-admin连接端-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置文件
如果你不想开启安全认证请参考以下的配置。
admin-server 未开启安全认证
server:
port: 7001
spring:
application:
name: admin-client
# 配置spring-boot-admin服务端的地址
boot:
admin:
client:
url: 'http://localhost:8001/admin-server'
#展示全部细节信息
management:
endpoints:
web:
exposure:
include: '*'
#允许admin工程远程停止本应用
endpoint:
health:
enabled: true
show-details: always
shutdown:
enabled: true
admin-server 开启安全认证
server:
port: 7001
spring:
application:
name: admin-client
# 配置spring-boot-admin服务端的地址
boot:
admin:
client:
url: 'http://localhost:8001/admin-server'
username: admin
password: admin
#展示全部细节信息
management:
endpoints:
web:
exposure:
include: '*'
#允许admin工程远程停止本应用
endpoint:
health:
enabled: true
show-details: always
shutdown:
enabled: true
查看Admin-Server端页面


如何实现服务 告警通知
当我们的服务发生异常时, 可以通过邮件、微信、钉钉等发送告警信息。
Server 端新增以下配置类。
@Component
public class AdminNotifier extends AbstractStatusChangeNotifier {
private static final Logger log = LoggerFactory.getLogger(AdminNotifier.class);
/**
* 消息模板
*/
private static final String template = "<<<%s>>> \n 【服务名】: %s(%s) \n 【状态】: %s(%s) \n 【服务ip】: %s \n 【详情】: %s";
private String titleAlarm = "系统告警";
private String titleNotice = "系统通知";
private String[] ignoreChanges = new String[]{"UNKNOWN:UP", "DOWN:UP", "OFFLINE:UP"};
public AdminNotifier(InstanceRepository repository) {
super(repository);
}
@Override
protected boolean shouldNotify(InstanceEvent event, Instance instance) {
if (!(event instanceof InstanceStatusChangedEvent)) {
return false;
} else {
InstanceStatusChangedEvent statusChange = (InstanceStatusChangedEvent) event;
String from = this.getLastStatus(event.getInstance());
String to = statusChange.getStatusInfo().getStatus();
return Arrays.binarySearch(this.ignoreChanges, from + ":" + to) < 0 && Arrays.binarySearch(this.ignoreChanges, "*:" + to) < 0 && Arrays.binarySearch(this.ignoreChanges, from + ":*") < 0;
}
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
if (event instanceof InstanceStatusChangedEvent) {
log.info("Instance {} ({}) is {}", instance.getRegistration().getName(),
event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());
String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
String messageText = null;
switch (status) {
// 健康检查没通过
case "DOWN":
log.info("发送 健康检查没通过 的通知!");
messageText = String
.format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "健康检查没通过通知",
instance.getRegistration().getServiceUrl(), JSONObject.toJSONString(instance.getStatusInfo().getDetails()));
log.info(messageText);
break;
// 服务离线
case "OFFLINE":
log.info("发送 服务离线 的通知!");
messageText = String
.format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务离线通知",
instance.getRegistration().getServiceUrl(), JSONObject.toJSONString(instance.getStatusInfo().getDetails()));
log.info(messageText);
break;
//服务上线
case "UP":
log.info("发送 服务上线 的通知!");
messageText = String
.format(template, titleNotice, instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务上线通知",
instance.getRegistration().getServiceUrl(), JSONObject.toJSONString(instance.getStatusInfo().getDetails()));
log.info(messageText);
break;
// 服务未知异常
case "UNKNOWN":
log.info("发送 服务未知异常 的通知!");
messageText = String
.format(template, titleAlarm, instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(), "服务未知异常通知",
instance.getRegistration().getServiceUrl(), JSONObject.toJSONString(instance.getStatusInfo().getDetails()));
log.info(messageText);
break;
default:
break;
}
} else {
log.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
event.getType());
}
});
}
}
如下图所示:

文章参考:
https://juejin.cn/post/7124624039921844232
https://juejin.cn/post/7141272117277884447
【Springboot】SpringBoot-Admin 服务监控+告警通知的更多相关文章
- SpringBoot系列——admin服务监控
前言 springboot项目部署起来后,如何实时监控项目的运行状况呢?本文记录使用springboot-admin对服务进行监控. springboot-admin介绍:https://codece ...
- Spring-Boot之Admin服务监控-9
一.Spring Boot Admin用于管理和监控一个或者多个Spring Boot程序.Spring Boot Admin分为Server端和Client 端,Client端可以通过向Http S ...
- SpringCloud微服务实战——搭建企业级开发框架(四十四):【微服务监控告警实现方式一】使用Actuator + Spring Boot Admin实现简单的微服务监控告警系统
业务系统正常运行的稳定性十分重要,作为SpringBoot的四大核心之一,Actuator让你时刻探知SpringBoot服务运行状态信息,是保障系统正常运行必不可少的组件. spring-b ...
- SpringCloud微服务实战——搭建企业级开发框架(四十五):【微服务监控告警实现方式二】使用Actuator(Micrometer)+Prometheus+Grafana实现完整的微服务监控
无论是使用SpringBootAdmin还是使用Prometheus+Grafana都离不开SpringBoot提供的核心组件Actuator.提到Actuator,又不得不提Micrometer ...
- 第七模块 :微服务监控告警Prometheus架构和实践
119.监控模式分类~1.mp4 logging:日志监控,Logging 的特点是,它描述一些离散的(不连续的)事件. 例如:应用通过一个滚动的文件输出 Debug 或 Error 信息,并通过日志 ...
- Spring Cloud第十三篇 | Spring Boot Admin服务监控
本文是Spring Cloud专栏的第十三篇文章,了解前十二篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Clo ...
- springcloud(九) springboot Actuator + admin 监控
前一章讲的都是Feign项目(调用方)的监控.接下来讲的是服务提供方的监控 一.springboot actuator + springboot admin Spring Boot Admin 是一个 ...
- SpringBoot服务监控
SpringBoot服务监控分为客户端和服务端,即服务端是监控方,客户端为被监控方. 例如需要对线上的SpringBoot服务project-A进行监控,则project-A 为客户端.而监控的服务p ...
- SpringBoot Admin应用监控搭建
简介 Spring Boot Admin 用于监控基于 Spring Boot 的应用,它是在 Spring Boot Actuator 的基础上提供简洁的可视化 WEB UI. 参考手册地址:htt ...
- 面试官:聊一聊SpringBoot服务监控机制
目录 前言 SpringBoot 监控 HTTP Endpoints 监控 内置端点 health 端点 loggers 端点 metrics 端点 自定义监控端点 自定义监控端点常用注解 来,一起写 ...
随机推荐
- mariadb修改用户host的两种方式
问题描述:使用update user set host='%' where user='root';修改用户host失败.根据提示mariadb不在是一个基表,而是一张视图,无法被直接修改.mysql ...
- Mysql Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘xx‘
MySql执行分组sql报错: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated co ...
- class类 和 react类组件
类的理解 1 // 创建一个person类 2 class Person { 3 /* */ 4 // 构造器方法 5 constructor(name, age) { 6 // this指向 =& ...
- Vue实战案例
Vue项目案例 结合之前学习的 vue.js.脚手架.vuex.vue-router.axios.elementui 等知识点,来开发前端项目案例(仅前端不含后端). 1.项目搭建 其实就是将我们项目 ...
- 2022-04-23:给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 使得 A 集合和 B 集合不为空,并且 average(A) == aver
2022-04-23:给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 使得 A 集合和 B 集合不为空,并且 average(A) == aver ...
- 文心一言 VS chatgpt (4)-- 算法导论2.2 1~2题
一.用O记号表示函数(n ^ 3)/1000-100(n^2)-100n十3. 文心一言: chatgpt: 可以使用大 O 记号表示该函数的渐进复杂度,即: f ( n ) = n 3 1000 − ...
- 2022-10-10:以下go语言代码输出什么?A:[1 2 3 0 1 2];B:死循环;C:[1 2 3 1 2 3];D:[1 2 3]。 package main import “fmt“
2022-10-10:以下go语言代码输出什么?A:[1 2 3 0 1 2]:B:死循环:C:[1 2 3 1 2 3]:D:[1 2 3]. package main import "f ...
- 2022-10-07:给定员工的 schedule 列表,表示每个员工的工作时间。 每个员工都有一个非重叠的时间段 Intervals 列表,这些时间段已经排好序。 返回表示 所有 员工的 共同,正
2022-10-07:给定员工的 schedule 列表,表示每个员工的工作时间. 每个员工都有一个非重叠的时间段 Intervals 列表,这些时间段已经排好序. 返回表示 所有 员工的 共同,正数 ...
- 2022-04-21:给定一个包含 [0,n) 中不重复整数的黑名单 blacklist, 写一个函数从 [0, n) 中返回一个不在 blacklist 中的随机整数, 对它进行优化使其尽量少调用系
2022-04-21:给定一个包含 [0,n) 中不重复整数的黑名单 blacklist, 写一个函数从 [0, n) 中返回一个不在 blacklist 中的随机整数, 对它进行优化使其尽量少调用系 ...
- 数据挖掘实践(金融风控):金融风控之贷款违约预测挑战赛(上篇)[xgboots/lightgbm/Catboost等模型]--模型融合:stacking、blending
数据挖掘实践(金融风控):金融风控之贷款违约预测挑战赛(上篇)[xgboots/lightgbm/Catboost等模型]--模型融合:stacking.blending 1.赛题简介 赛题以金融风控 ...