Springboot 多数据源进行actuator监控

Springboot 多数据源进行actuator监控

本文介绍Springboot多数据源使用Prometheus进行监控。

环境

springboot 2.0.8.RELEASE
spring-boot-starter-parent 2.0.8.RELEASE
micrometer-registry-prometheus 1.0.9
mybatis-plus-boot-starter 3.1.0
dynamic-datasource-spring-boot-starter 3.4.1

prometheus:v2.4.0 查看的1.8的文档

进行prometheus 查看此博客

1.配置多数据源的项目

pom



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.8.RELEASE
         
    
    com.dalaoyang
    springcloud_prometheus_dynamic_datasource
    0.0.1-SNAPSHOT
    springcloud_prometheus_dynamic_datasource
    springcloud_prometheus_dynamic_datasource

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.1.0
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            com.baomidou
            dynamic-datasource-spring-boot-starter
            3.4.1
        

        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
        
        
            io.micrometer
            micrometer-registry-prometheus
            1.0.9
        
        
            io.github.mweirauch
            micrometer-jvm-extras
            0.1.2
        
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

    
        
            spring-milestones
            Spring Milestones
            https://repo.spring.io/milestone
        
    



application.yml

spring:
  application:
    name: springcloud_prometheu_dynamic_datasource
  ##数据库url
  datasource:
    dynamic:
      primary: mysql
      strict: true
      datasource:
        mysql:
          url: jdbc:mysql://192.168.0.229:43306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: Cobbler1234!
          hikari:
            minIdle: 10
            maxPoolSize: 80
            connectionTimeout: 10000
            idleTimeout: 300000
            maxLifetime: 1800000
            connectionTestQuery: SELECT 1
            validationTimeout: 5000
            initializationFailTimeout: 1
        scsdb_1:
          username: SCS
          password: 123456
          url: jdbc:mysql://192.168.0.76:2200/bigdata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
          driver-class-name: com.mysql.jdbc.Driver
          hikari:
            minIdle: 10
            maxPoolSize: 80
            connectionInitSql: set slave;start backup;
            connectionTimeout: 10000
            idleTimeout: 300000
            maxLifetime: 1800000
            connectionTestQuery: SELECT 1
            validationTimeout: 5000
            initializationFailTimeout: 1
        scsop_1:
          username: SCS
          password: 123456
          url: jdbc:mysql://192.168.0.76:2200/bigdata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
          driver-class-name: com.mysql.jdbc.Driver
          hikari:
            minIdle: 10
            maxPoolSize: 80
            connectionInitSql: set slave;start backup;
            connectionTimeout: 10000
            idleTimeout: 300000
            maxLifetime: 1800000
            connectionTestQuery: SELECT 1
            validationTimeout: 5000
            initializationFailTimeout: 1

server:
  port: 9905

management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: env,beans
  endpoint:
    metrics:
      enabled: true
    prometheus:
      enabled: true
  metrics:
    tags:
      application: ${spring.application.name}
    export:
      prometheus:
        enabled: true

启动类

package com.liuhm;

import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringcloudPrometheuDynamicDatasourceApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudPrometheuDynamicDatasourceApplication.class, args);
    }

    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer(
            @Value("${spring.application.name}") String applicationName) {
        return (registry) -> registry.config().commonTags("application", applicationName);
    }
}


2. 测试,检查数据源情况

访问 http://localhost:9904/actuator/prometheus

Springboot 多数据源进行actuator监控_第1张图片

发现只有mysql数据源,没得其他数据源

在这里插入图片描述

3.查找问题

发现只绑定了一个数据源的配置信息
Springboot 多数据源进行actuator监控_第2张图片

多数据源bean有全部的数据源信息
Springboot 多数据源进行actuator监控_第3张图片

4.解决问题

重写这个类的方法,在自己项目路径下创建org.springframework.boot.actuate.autoconfigure.metrics.jdbc

包,在此包创建HikariDataSourceMetricsPostProcessor,

修改如下
Springboot 多数据源进行actuator监控_第4张图片

/*
 * Copyright 2012-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.actuate.autoconfigure.metrics.jdbc;

import javax.sql.DataSource;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory;
import io.micrometer.core.instrument.MeterRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.jdbc.DataSourceUnwrapper;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;

import java.util.Map;

/**
 * {@link BeanPostProcessor} that configures Hikari metrics. Such arrangement is necessary
 * because a {@link HikariDataSource} instance cannot be modified once its configuration
 * has completed.
 *
 * @author Stephane Nicoll
 */
class HikariDataSourceMetricsPostProcessor implements BeanPostProcessor, Ordered {

    private static final Log logger = LogFactory
            .getLog(HikariDataSourceMetricsPostProcessor.class);

    private final ApplicationContext context;

    private volatile MeterRegistry meterRegistry;

    HikariDataSourceMetricsPostProcessor(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        HikariDataSource hikariDataSource = determineHikariDataSource(bean);
        if (hikariDataSource != null) {
            Map<String, DataSource> dataSourceMap = ((DynamicRoutingDataSource) bean).getDataSources();
            for(String key: dataSourceMap.keySet()){
                HikariDataSource dataSource = determineHikariDataSource(dataSourceMap.get(key));
                bindMetricsRegistryToHikariDataSource(getMeterRegistry(), dataSource );
            }
        }
        return bean;
    }

    private HikariDataSource determineHikariDataSource(Object bean) {
        if (bean instanceof DataSource) {
            return DataSourceUnwrapper.unwrap((DataSource) bean, HikariDataSource.class);
        }
        return null;
    }

    private void bindMetricsRegistryToHikariDataSource(MeterRegistry registry,
                                                       HikariDataSource dataSource) {
        if (!hasExisingMetrics(dataSource)) {
            try {
                dataSource.setMetricsTrackerFactory(
                        new MicrometerMetricsTrackerFactory(registry));
            }
            catch (Exception ex) {
                logger.warn("Failed to bind Hikari metrics: " + ex.getMessage());
            }
        }
    }

    private boolean hasExisingMetrics(HikariDataSource dataSource) {
        return dataSource.getMetricRegistry() != null
                || dataSource.getMetricsTrackerFactory() != null;
    }

    private MeterRegistry getMeterRegistry() {
        if (this.meterRegistry == null) {
            this.meterRegistry = this.context.getBean(MeterRegistry.class);
        }
        return this.meterRegistry;
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

}

多模块导入的情况下,该方法失效,就再将DataSourcePoolMetricsAutoConfiguration进行重写 ,在加个注解 @Primary
Springboot 多数据源进行actuator监控_第5张图片

5. 测试

都有了
Springboot 多数据源进行actuator监控_第6张图片

代码下载

你可能感兴趣的:(prometheus,spring,boot,java,后端,prometheus)