SpringBootAdmin微服务监控

创建Server

SpringBootAdmin通过收集actuator暴露出来的服务信息以及通过心跳检测的机制判断服务的运行状况。

1.引入依赖

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

2. 启动类手动装配AdminServer

@EnableAdminServer
@SpringBootApplication
public class MicroAdminApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(MicroAdminApplication.class, args);
    }
 
}

3. 配置服务发现

eureka

eureka:
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
  client:
    fetch-registry: true
    registry-fetch-interval-seconds: 5
    serviceUrl:
      defaultZone: http://10.2.1.5:9001/eureka/,http://10.2.1.6:9001/eureka/

nacos

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.174.137:8848

服务器端配置完毕!

4. 接入SpringSecurity

保证登录安全,可以不接

引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
指定登录页面为SpringBootAdmin
@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" );
 
        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()
                .httpBasic().and()
                .csrf().disable();
    }
}
配置登录密码
spring:
  security:
    user:
      name: 'admin'
      password: 'admin'

Client接入

1. 引入依赖

该依赖已经包含spring-boot-starter-actuator不需要重复引入

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.2.0</version>
</dependency>

2. 配置暴露的端点信息

management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: ALWAYS

[注意]
默认会检查redis的健康状况,如果你的服务没有依赖redis,需要额外增加配置,关掉redis的健康检查。否则会报异常。

management:
  health:
    redis:
      enabled: false

依次启动Server和Client,浏览器登录{server.ip}:{port}访问springBootAdmin,此时服务已经接入成功


应用详情可查看应用具体的状况

Server端使用报警提示功能

接入邮箱报警提示

引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置邮箱信息
spring:
  boot:
    admin:
      notify:
        mail:
          to: yuwenbo10@jd.com
          from: 18629015421@163.com
  mail:
    host: smtp.163.com
    password: '******'
    username: 18629015421@163.com

【注意】
此处的邮箱密码不是我们设定的邮箱密码,需要登录到对应的邮箱官网去设置smtp的授权码,此处参照百度百科https://jingyan.baidu.com/article/295430f1fc28a60c7e0050f9.html

再次重启admin Server 如果有服务发生任何变动会给配置的邮箱发送邮件
eg:


自定义报警

SpringBootAdmin 发送邮件的原理是基于事件的监听机制,类似于观察者模式,具体的类
de.codecentric.boot.admin.server.notify.MailNotifier
部分源码如下:

public class MailNotifier extends AbstractStatusChangeNotifier {
    private final JavaMailSender mailSender;
    private final TemplateEngine templateEngine;
    private String[] to = new String[]{"root@localhost"};
    private String[] cc = new String[0];
    private String from = "Spring Boot Admin <noreply@localhost>";
    private Map<String, Object> additionalProperties = new HashMap();
    @Nullable
    private String baseUrl;
    private String template = "classpath:/META-INF/spring-boot-admin-server/mail/status-changed.html";
 
    public MailNotifier(JavaMailSender mailSender, InstanceRepository repository, TemplateEngine templateEngine) {
        super(repository);
        this.mailSender = mailSender;
        this.templateEngine = templateEngine;
    }
 
    /**
     * 服务发送变动,会调用该方法发送邮件
     */
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            Context ctx = new Context();
            ctx.setVariables(this.additionalProperties);
            ctx.setVariable("baseUrl", this.baseUrl);
            ctx.setVariable("event", event);
            ctx.setVariable("instance", instance);
            ctx.setVariable("lastStatus", this.getLastStatus(event.getInstance()));
 
            try {
                MimeMessage mimeMessage = this.mailSender.createMimeMessage();
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage, StandardCharsets.UTF_8.name());
                message.setText(this.getBody(ctx).replaceAll("\\s+\\n", "\n"), true);
                message.setSubject(this.getSubject(ctx));
                message.setTo(this.to);
                message.setCc(this.cc);
                message.setFrom(this.from);
                this.mailSender.send(mimeMessage);
            } catch (MessagingException var6) {
                throw new RuntimeException("Error sending mail notification", var6);
            }
        });
    }
 
 
.....次数省略若干行
 
 
}

1.自定义邮件模板

可以看出邮件模板的存放路径是

/META-INF/spring-boot-admin-server/mail/status-changed.html
我们可以在自己项目目录下创建模板进行替换。

2. 更改邮件级别

不知道标题写啥,就写级别吧,默认情况下服务的上线,下线,离线,未知,等等状态都会发邮件,服务的状态在类Instance的StatusInfo里面使用6个String类型的常量来进行描述

部分源码:

public final class StatusInfo implements Serializable {
 
   public static final String STATUS_UNKNOWN = "UNKNOWN";
 
   public static final String STATUS_OUT_OF_SERVICE = "OUT_OF_SERVICE";
 
   public static final String STATUS_UP = "UP";
 
   public static final String STATUS_DOWN = "DOWN";
 
   public static final String STATUS_OFFLINE = "OFFLINE";
 
   public static final String STATUS_RESTRICTED = "RESTRICTED";
 
   .....
}

我们可以继承抽象类AbstractStatusChangeNotifier并重写doNotify方法,定制化邮件发送。

3. 做点别的?

有时候我们想既发送邮件,也发送短信的形式来保证服务出现问题第一时间感知,我们可以自己编写一个类继承AbstractStatusChangeNotifier实现onNotify方法具体写自己的短信逻辑就可以了,但是我们会发现,这样操作的话,每次只会发送短信,不会发送默认的邮件了,这是由于mailNotifier使用自动装配机制(不了解自动装配的可以查看这篇文章https://www.jianshu.com/p/c56c34c1c876
),并通过@ConditionOnMissingBean注解控制,如果Spring容器中有AbstractStatusChangeNotifier实例了,就不会注入mailNotifier,具体的解决方案可以是这样的,复制他的代码,然后去掉@ConditionOnMissingBean注解就可以了。

@Configuration
public class BeanFactory {
 
 
    @AutoConfigureBefore({AdminServerNotifierAutoConfiguration.NotifierTriggerConfiguration.class, AdminServerNotifierAutoConfiguration.CompositeNotifierConfiguration.class})
    @ConditionalOnBean({MailSender.class})
    public static class MailNotifierConfiguration {
        private final ApplicationContext applicationContext;
 
        public MailNotifierConfiguration(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }
 
        @Bean
        @ConfigurationProperties("spring.boot.admin.notify.mail")
        public MailNotifier mailNotifier(JavaMailSender mailSender, InstanceRepository repository) {
            return new MailNotifier(mailSender, repository, this.mailNotifierTemplateEngine());
        }
 
        @Bean
        public TemplateEngine mailNotifierTemplateEngine() {
            SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
            resolver.setApplicationContext(this.applicationContext);
            resolver.setTemplateMode(TemplateMode.HTML);
            resolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
            SpringTemplateEngine templateEngine = new SpringTemplateEngine();
            templateEngine.addTemplateResolver(resolver);
            return templateEngine;
        }
    }
}

4.分布式监控

这里只说一点点,就是我们生产环境,一般SpringBootAdmin Server也需要进行集群部署,但是如果服务发生问题,相同的邮件会发送多份,所以需要使用分布式锁的机制,如果你的分布式锁是基于AOP实现,不能直接放在onNotify方法上,因为这个方法的访问权限是protected,需要将方法的访问级别提升为public,可能也不好使,还是使用编码的形式吧~

参考链接:
https://www.cnblogs.com/forezp/p/10242004.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容