spring boot admin 的使用
当我们在 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/
推荐阅读
-
spring boot 打jar包,获取resource路径下的文件
-
Apache shiro的简单介绍与使用教程(与spring整合使用)
-
Spring Boot 2.X整合Spring-cache(让你的网站速度飞起来)
-
SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - SpringBoot如何实现SpringMvc的?
-
SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)
-
[Spring Boot]使用自定义注解统一请求返回值
-
Spring 使用JavaConfig实现配置的方法步骤
-
Spring boot @ModelAttribute标注的实现
-
spring boot启动时加载外部配置文件的方法
-
Spring Boot 入门之消息中间件的使用