Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。 应用程序做为Spring Boot Admin Client向为Spring Boot Admin Server注册(经过HTTP)或使用SpringCloud注册中心(例如Eureka,Consul)发现。 UI是的Vue.js应用程序,展现Spring Boot Admin Client的Actuator端点上的一些监控。服务端采用Spring WebFlux + Netty的方式。Spring Boot Admin为注册的应用程序提供如下功能:php
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>admin-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>admin-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.0</spring-boot-admin.version>
</properties>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
spring:
application:
name: admin-server
server:
port: 8769
复制代码
启动类加上@EnableAdminServer注解,开启AdminServer的功能:java
@SpringBootApplication
@EnableAdminServer
public class AdminServerApplication {
public static void main(String[] args) {
SpringApplication.run( AdminServerApplication.class, args );
}
}
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>admin-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>admin-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.0</spring-boot-admin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
spring:
application:
name: admin-client
boot:
admin:
client:
url: http://localhost:8769
server:
port: 8768
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
复制代码
@SpringBootApplication
public class AdminClientApplication {
public static void main(String[] args) {
SpringApplication.run( AdminClientApplication.class, args );
}
}
复制代码
启动两个工程,在浏览器上输入localhost:8769 ,浏览器显示的界面以下:git
查看wallboard:github
点击wallboard,能够查看admin-client具体的信息,好比内存状态信息:web
查看spring bean的状况:redis
查看应用程序运行情况,信息和详细:spring
还有不少监控信息,多点一点就知道。数据库
这是一个 eureka-server 注册中心。apache
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>sc-admin-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sc-admin-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.0</spring-boot-admin.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<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.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
spring:
application:
name: sc-eureka-server
server:
port: 8761
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
register-with-eureka: false
fetch-registry: false
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
复制代码
@SpringBootApplication
@EnableEurekaServer
public class ScEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run( ScEurekaServerApplication.class, args );
}
}
复制代码
这是一个 Spring Boot Admin Server端。浏览器
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>sc-admin-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sc-admin-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.0</spring-boot-admin.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<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.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
spring:
application:
name: admin-server
server:
port: 8769
eureka:
client:
registryFetchIntervalSeconds: 5
service-url:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /actuator/health
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
复制代码
@SpringBootApplication
@EnableAdminServer
@EnableDiscoveryClient
public class ScAdminServerApplication {
public static void main(String[] args) {
SpringApplication.run( ScAdminServerApplication.class, args );
}
}
复制代码
这是一个 Spring Boot Admin client 端。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>sc-admin-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sc-admin-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.1.0</spring-boot-admin.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-dependencies</artifactId>
<version>${spring-boot-admin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
spring:
application:
name: sc-admin-client
eureka:
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /actuator/health
client:
registryFetchIntervalSeconds: 5
service-url:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: ALWAYS
server:
port: 8762
复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class ScAdminClientApplication {
public static void main(String[] args) {
SpringApplication.run( ScAdminClientApplication.class, args );
}
}
复制代码
启动三个工程,访问localhost:8769,出现以下界面:
admin 会本身拉取 Eureka 上注册的 app 信息,主动去注册。这也是惟一区别以前入门中手动注册的地方,就是 client 端不须要 admin-client 的依赖,也不须要配置 admin 地址了,一切所有由 admin-server 本身实现。这样的设计对环境变化很友好,不用改了admin-server后去改全部app 的配置了。
Web应用程序中的身份验证和受权有多种方法,所以Spring Boot Admin不提供默认方法。默认状况下,spring-boot-admin-server-ui提供登陆页面和注销按钮。咱们结合 Spring Security 实现须要用户名和密码登陆的安全认证。
sc-admin-server工程的pom文件须要增长如下的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
复制代码
在 sc-admin-server工的配置文件 application.yml 中配置 spring security 的用户名和密码,这时须要在服务注册时带上 metadata-map 的信息,以下:
spring:
security:
user:
name: "admin"
password: "admin"
eureka:
instance:
metadata-map:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
复制代码
@EnableWebSecurity注解以及WebSecurityConfigurerAdapter一块儿配合提供基于web的security。继承了WebSecurityConfigurerAdapter以后,再加上几行代码,咱们就能实现要求用户在进入应用的任何URL以前都进行验证的功能,写一个配置类SecuritySecureConfig继承WebSecurityConfigurerAdapter,配置以下:
@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 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支持。这是Spring Boot Admin Client注册所必需的
.httpBasic().and();
// @formatter:on
}
}
复制代码
从新访问 http://localhost:8769/ 会出现登陆界面,密码是 配置文件中配置好的,帐号 admin 密码 admin,界面以下:
在 Spring Boot Admin 中 当注册的应用程序状态更改成DOWN、UNKNOWN、OFFLINE 均可以指定触发通知,下面讲解配置邮件通知。
在sc-admin-server工程pom文件,加上mail的依赖,以下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
复制代码
在配置文件application.yml文件中,配置收发邮件的配置:
spring:
mail:
host: smtp.163.com
username: xxxx@163.com
password: xxxx
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
boot:
admin:
notify:
mail:
from: xxxx@163.com
to: xxxx@qq.com
复制代码
配置后,重启sc-admin-server工程,以后若出现注册的客户端的状态从 UP 变为 OFFLINE 或其余状态,服务端就会自动将电子邮件发送到上面配置的收件地址。
注意 : 配置了邮件通知后,会出现 反复通知 service offline / up。这个问题的缘由在于 查询应用程序的状态和信息超时,下面给出两种解决方案:
#方法一:增长超时时间(单位:ms)
spring.boot.admin.monitor.read-timeout=20000
#方法二:关闭闭未使用或不重要的检查点
management.health.db.enabled=false
management.health.mail.enabled=false
management.health.redis.enabled=false
management.health.mongo.enabled=false
复制代码
能够经过添加实现Notifier接口的Spring Beans来添加您本身的通知程序,最好经过扩展 AbstractEventNotifier或AbstractStatusChangeNotifier。在sc-admin-server工程中编写一个自定义的通知器:
@Component
public class CustomNotifier extends AbstractStatusChangeNotifier {
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());
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:
break;
}
} else {
LOGGER.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
event.getType());
}
});
}
}
复制代码