当我们在 spring boot 程序中引入 spring-boot-starter-actuator 之后,我们的应用程序中会存在多个监控的端点,用于监控程序的健康状态,但是这些端点都是以 restful 格式返回数据,不利于阅读,那么有没有一个图形化的界面可以解决这个问题呢?spring boot admin 正好可以帮助我们解决这个问题。
当我们使用了 spring cloud 之后,我们只需要将 spring boot admin server 作为一个服务发现者注册到spring cloud 的注册中心上去,对于spring boot admin 的客户端如果也是注册到了 spring cloud上,那么就不用在引入额外的jar包,如果没有注册到 spring cloud上,那么需要引入 spring-boot-admin-starter-client 依赖,此处考虑都注册到了spring cloud的请求下。
实现功能:
admin server:
>> 引入 spring security 保护admin server
>> 作为一个服务发现者注册到 eureka 上
>> 给 admin server 提供一个表单登录
>> 服务状态的改变,给相应的人发送邮件通知
admin client:
>> 动态控制日志级别
>> 当设置了management.context-path,如何进行配置
>> 显示版本号
>> 客户端使用了 spring security 做了权限保护,admin server如何访问
>> 整合hystrix ui
一、spring boot admin server 的编写
①、引入 admin-server 依赖
<dependencies>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
</dependencies>
②、配置文件的写法
server:
port: 8401
eureka:
client:
service-url:
defaultZone : http://${security.user.name}:${security.user.password}@localhost:8761/eureka/ #连接到服务注册中心的地址,如果服务注册中心开启了权限需要设置 http://username:password@ip:port/eureka/格式
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${server.port}
# 客户端与服务器断心跳的时间间隔,默认为 30秒
lease-renewal-interval-in-seconds: 3
# 租约到期时间,此值不可过小,开发环境小点没有事,默认为 90秒
lease-expiration-duration-in-seconds: 9
security:
user:
name: root
password: admin
spring:
application:
name: spring-boot-admin-server
boot:
admin:
context-path: /admin
management:
security:
enabled: false
logging:
path: logs
info:
app:
name: "spring-boot-admin-server-8401"
description: "spring-boot-admin-server-8401程序"
version: "0.0.1"
注意:
1、需要指定 spring security 的用户名和密码
2、需要将 management.security.enabled 的值设置成 false
3、指定 logging.path 的值方便看日志
4、设置了程序的启动端口为 8401, 程序的 contextPath 为 /admin
③、启动类上增加 @EnableAdminServer
@SpringBootApplication
@EnableDiscoveryClient
@EnableAdminServer
public class AdminServer8401 {
public static void main(String[] args) {
SpringApplication.run(AdminServer8401.class, args);
}
}
④、admin server 的运行结果
⑤、实现以上功能后,为admin server 提供一个表单登陆功能
>> 引入依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-login</artifactId>
<version>1.5.7</version>
</dependency>
>> 配置 spring security 的配置
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private AdminServerProperties adminServerProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
String contextPath = adminServerProperties.getContextPath();
http.formLogin().loginPage(contextPath + "/login.html").loginProcessingUrl(contextPath + "/login").defaultSuccessUrl(contextPath+"/").permitAll();
http.logout().logoutUrl(contextPath + "/logout");
http.csrf().disable();
http.authorizeRequests()
.antMatchers(contextPath + "/login.html", "/**/*.css", contextPath + "/img/**", contextPath + "/third-party/**")
.permitAll();
http.authorizeRequests().antMatchers("/**").authenticated();
http.httpBasic();
}
}
>> 登陆界面
⑥、当服务上线或下线后给相应的人进行邮件通知
一、引入 邮件依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
二、在配置文件中配置 Java mail 配置
spring:
mail:
default-encoding: UTF-8
host: smtp.exmail.qq.com
password: 邮箱的用户名
username: 邮箱的密码
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
注意:
此处需要根据自己的请求请求修改,我这个地方是QQ企业邮箱的配置
三、完成通知
/**
* @author huan.fu
* 应用程序上下线通知
*/
@Configuration
@EnableScheduling
public class NotifierConfiguration {
private static final Logger log = LoggerFactory.getLogger(NotifierConfiguration.class);
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private RemindingNotifier remindingNotifier;
@Bean
@Primary
public RemindingNotifier remindingNotifier() {
RemindingNotifier remindingNotifier = new RemindingNotifier(new AbstractEventNotifier() {
@Override
protected void doNotify(ClientApplicationEvent event) throws Exception {
if (event instanceof ClientApplicationStatusChangedEvent) {
ClientApplicationStatusChangedEvent changedEvent = (ClientApplicationStatusChangedEvent) event;
log.info("Application {} ({}) is {}", event.getApplication().getName(), event.getApplication().getId(), changedEvent.getTo().getStatus());
String text = String.format("应用:%s 服务ID:%s,服务ip:%s 状态改变为:[%s ---> %s],时间:%s"
, event.getApplication().getName()
, event.getApplication().getId()
, event.getApplication().getHealthUrl()
, ((ClientApplicationStatusChangedEvent) event).getFrom().getStatus()
, ((ClientApplicationStatusChangedEvent) event).getTo().getStatus()
, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(changedEvent.getTimestamp())));
log.warn(text);
SimpleMailMessage message = new SimpleMailMessage();
message.setTo("收件人邮箱");
message.setFrom("发件人邮箱");
message.setSubject("服务状态改变");
message.setText(text);
javaMailSender.send(message);
} else {
log.info("Application {} ({}) {}", event.getApplication().getName(), event.getApplication().getId(), event.getType());
}
}
});
// 每5分钟就需要提醒一次,并不一定会提醒,有RemindingNotifier里面的状态进行决定
remindingNotifier.setReminderPeriod(TimeUnit.MINUTES.toMillis(5));
return remindingNotifier;
}
/**
* 每隔一分钟检查还有那些需要进行提醒
*/
@Scheduled(fixedRate = 1_000L)
public void remind() {
remindingNotifier.sendReminders();
}
}
注意:
如果不想使用邮件通知,只需要实现 对应的 Notifier 接口即可,在 doNotify 方法中进行自己的提醒逻辑。
二、client 的写法
客户端就是一个普通的 spring cloud 服务
①、如果需要显示版本号,那么pom文件中需要加入
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
页面效果
②、如果配置了 management.context-path 那么配置应该如下
management.security.enabled 的值也需要设置成 false
③、动态管理日志的级别
④、客户端使用了 spring security 做了权限保护,admin server如何访问
admin client 操作步骤:
1、在 spring security 中启用 basic 认证
2、在 eureka 的 metadata-map中配置登录的用户名和密码、
⑤、整合hystrix ui
1、引入以下依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-hystrix</artifactId>
<version>1.5.7</version>
</dependency>
2、application.yml文件中新增如下配置
spring.boot.admin.routes.endpoints: env,metrics,dump,jolokia,info,configprops,trace,logfile,refresh,flyway,liquibase,heapdump,loggers,auditevents,hystrix.stream
三、完整的运行结果
>> 演示使用 form 表单进行登录
>> 演示输出版本号
>> 演示动态控制日志的级别
四、完整代码
1、spring boot admin server 代码:https://gitee.com/huan1993/spring-cloud-parent/tree/master/monitor/admin
2、spring-boot-admin-server 文档:http://codecentric.github.io/spring-boot-admin/1.5.7/