Spring Cloud之——SpringBootAdmin监控程序

简介

Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册(通过HTTP)或使用SpringCloud注册中心(例如Eureka,Consul)发现。 UI是的AngularJs应用程序,展示Spring Boot Admin Client的Actuator端点上的一些监控。常见的功能或者监控如下:

  • 显示健康状况
  • 显示详细信息,例如
    JVM和内存指标
    micrometer.io指标
    数据源指标
    缓存指标
  • 显示构建信息编号
  • 关注并下载日志文件
  • 查看jvm系统和环境属性
  • 查看Spring Boot配置属性
  • 支持Spring Cloud的postable / env-和/ refresh-endpoint
  • 轻松的日志级管理
  • 与JMX-beans交互
  • 查看线程转储
  • 查看http跟踪
  • 查看auditevents
  • 查看http-endpoints
  • 查看计划任务
  • 查看和删除活动会话(使用spring-session)
  • 查看Flyway / Liquibase数据库迁移
  • 下载heapdump
  • 状态变更通知(通过电子邮件,Slack,Hipchat,…)
  • 状态更改的事件日志(非持久性)

引用Pom


		<!--    发送邮件    -->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</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-actuator</artifactId>
        </dependency>

		<!--    SpringBootAdmin    -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.2.3</version>
        </dependency>

		<!--    服务注册    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            <version>2.2.3.RELEASE</version>
        </dependency>
        

Yml文件

spring:
  application:
    name: spring-boot-admin
  main:
    allow-bean-definition-overriding: true

  boot:
    admin:
      discovery:
        ignored-services: consul
      #监控通知邮箱
      notify:
        mail:
          from: 邮箱账号
          to: 接收邮箱账号

  #配置邮箱
  mail:
    host: smtp.163.com
    username: 邮箱账号
    password: 授权码
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          #QQ邮箱必须加
          ssl:
            enable: true

  cloud:
    consul:
      #配置consul服务器的host
      host: localhost
      #配置端口
      port: 8500
      discovery:
        #配置健康检查时间间隔
        health-check-interval: 15s
        #配置实例id
        instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
        #配置服务注册
        register: true
        #表示注册时使用ip而不是hostname
        prefer-ip-address: true
        #健康检查失败多长时间取消注册
        health-check-critical-timeout: 30s

全局配置

新建全局配置类:MonkeyConfiguration

package com.admin.admin;

import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;

/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-09-29 15:03
 * @Modified By:
 */
@Configuration
public class MonkeyConfiguration {

    @Bean
    public MonkeyCompositeNotifier monkeyCompositeNotifier(InstanceRepository instanceRepository,
                                                           JavaMailSender mailSender) {
        return new MonkeyCompositeNotifier(instanceRepository, mailSender);
    }

}

新建消息模型:MessageBody

```java
package com.admin.admin.sendMessage.model;

/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-11-06 15:48
 * @Modified By:
 */
public class MessageBody {

    /**
     * 内容
     */
    private String text;

    /**
     * 标题
     */
    private String title;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

新建发送消息类:MonkeyCompositeNotifier

package com.admin.admin;

import com.admin.admin.sendMessage.SendAllMessage;
import com.admin.admin.sendMessage.model.MessageBody;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceDeregisteredEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceRegisteredEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.domain.values.Registration;
import de.codecentric.boot.admin.server.domain.values.StatusInfo;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import reactor.core.publisher.Mono;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-09-29 15:07
 * @Modified By:
 */
public class MonkeyCompositeNotifier extends AbstractEventNotifier {

    private static final Logger logger = LoggerFactory.getLogger(MonkeyCompositeNotifier.class);

    private JavaMailSender mailSender;

    @Value("${spring.boot.admin.notify.mail.from}")
    private String from;

    @Value("${spring.boot.admin.notify.mail.to}")
    private String to;

    private final static Map<Class<?>, BiFunction<InstanceEvent, Instance, MessageBody>> cacheMap = new HashMap<>();

    static {
        //注册
        cacheMap.put(InstanceRegisteredEvent.class, MonkeyCompositeNotifier::register);
        //注销
        cacheMap.put(InstanceDeregisteredEvent.class, MonkeyCompositeNotifier::deRegistered);
        //状态变更
        cacheMap.put(InstanceStatusChangedEvent.class, MonkeyCompositeNotifier::statusChanged);
    }

    public MonkeyCompositeNotifier(InstanceRepository repository, JavaMailSender mailSender) {
        super(repository);
        this.mailSender = mailSender;
    }

    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            BiFunction<InstanceEvent, Instance, MessageBody> messageBiFunction = cacheMap.get(event.getClass());
            if (messageBiFunction != null) {
                MessageBody messageBody = messageBiFunction.apply(event, instance);

                MimeMessage mimeMessage = mailSender.createMimeMessage();
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage, StandardCharsets.UTF_8.name());
                try {
                    message.setText(messageBody.getText());
                    message.setSubject(messageBody.getTitle());
                    message.setTo(to);
                    message.setFrom(from);
                    mailSender.send(mimeMessage);
                } catch (MessagingException e) {
                    e.printStackTrace();
                    logger.error("发送邮件异常!", e);
                }

            }
        });
    }

    /**
     * 注册通知
     *
     * @param event
     * @param instance
     * @return
     */
    private static MessageBody register(InstanceEvent event, Instance instance) {
        Registration registration = instance.getRegistration();
        MessageBody body = new MessageBody();
        body.setText("服务名称:" + registration.getName() + "  服务地址:" + registration.getServiceUrl());
        body.setTitle("服务上线通知!");
        return body;
    }

    /**
     * 注销通知
     *
     * @param event
     * @param instance
     * @return
     */
    private static MessageBody deRegistered(InstanceEvent event, Instance instance) {
        Registration registration = instance.getRegistration();
        MessageBody body = new MessageBody();
        body.setText("服务名称:" + registration.getName() + "  服务地址:" + registration.getServiceUrl());
        body.setTitle("服务下线通知!");
        return body;
    }

    /**
     * 状态变更通知
     *
     * @param event
     * @param instance
     * @return
     */
    private static MessageBody statusChanged(InstanceEvent event, Instance instance) {
        StatusInfo statusInfo = ((InstanceStatusChangedEvent) event).getStatusInfo();
        Registration registration = instance.getRegistration();
        MessageBody body = new MessageBody();
        body.setText("服务名称:" + registration.getName() + "  服务地址:" + registration.getServiceUrl() + "  状态:" + statusInfo.getStatus());
        body.setTitle("服务状态变量通知!");
        return body;
    }

}

如果看过源码的小伙伴知道,自带发送邮件服务继承AbstractStatusChangeNotifier,而我们需要重写他的方法是无法收到消息,这是为什么呢?
它有一个shouldNotify方法,把一些方法过滤了。所以我们继承AbstractEventNotifier

	@Override
	protected boolean shouldNotify(InstanceEvent event, Instance instance) {
		if (event instanceof InstanceStatusChangedEvent) {
			InstanceStatusChangedEvent statusChange = (InstanceStatusChangedEvent) event;
			String from = getLastStatus(event.getInstance());
			String to = statusChange.getStatusInfo().getStatus();
			return Arrays.binarySearch(ignoreChanges, from + ":" + to) < 0
					&& Arrays.binarySearch(ignoreChanges, "*:" + to) < 0
					&& Arrays.binarySearch(ignoreChanges, from + ":*") < 0;
		}
		return false;
	}

而且他本身的邮件通知只支持InstanceStatusChangedEvent(状态变更通知),没有注册、上下线通知,所以我们重写一个。

访问:http://localhost:8080出现管理界面

权限访问配置

  • 添加Pom文件
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
  • 配置文件
spring:
  security:
    user:
      name: "admin"
      password: "admin"

访问页面时候会弹出登录界面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值