zoukankan      html  css  js  c++  java
  • SpringBoot+HikariCP+Dropwizard-Metrics统计连接池使用情况

    SpringBoot+HikariCP+Dropwizard-Metrics统计连接池使用情况

    背景,HikariCP是Java目前使用最广的连接池工具类,SpringBoot默认也是用这个,现在想获取连接池使用情况。

    这里假设SpringBoot已集成HikariCP
    1.pom.xml加上Dropwizard-Metrics配置

    <dependency>
        <groupId>io.dropwizard.metrics</groupId>  
        <artifactId>metrics-core</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>io.dropwizard.metrics</groupId>  
        <artifactId>metrics-healthchecks</artifactId>  
    </dependency>  
    

    2在应用启动的时候连接池注册统计接口

    import com.codahale.metrics.MetricRegistry;    
    import com.codahale.metrics.Slf4jReporter;    
    import com.zaxxer.hikari.HikariDataSource;    
        
    import javax.sql.DataSource;    
    import org.slf4j.Logger;    
    import org.slf4j.LoggerFactory;    
    @Component    
    public class ApplicationRunner implements ApplicationRunner {    
        private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRunner.class);    
        @Autowired    
        private DataSource dataSource;    
        
        @Override    
        public void run(ApplicationArguments args) throws Exception {    
            try {    
                // see detail https://github.com/brettwooldridge/HikariCP/wiki/Dropwizard-Metrics    
                // 连接池注册统计接口    
                MetricRegistry metricRegistry = new MetricRegistry();    
                if(dataSource instanceof HikariDataSource) {    
                    ((HikariDataSource) dataSource).setMetricRegistry(metricRegistry);    
                }    
                // 定时打印连接池使用情况    
                Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry).build();    
                reporter.start(1, TimeUnit.MINUTES);    
        
            } catch (Exception e) {    
                String msg = "服务启动异常";    
                LOGGER.error(msg, e);    
                throw new IllegalStateException(msg, e);    
            }     
        
        
        }    
    }  
    
    

    3 提供http请求获取连接池使用情况

    import org.springframework.context.annotation.Bean;  
    import org.springframework.context.annotation.Configuration;  
    import org.springframework.http.client.SimpleClientHttpRequestFactory;  
    import org.springframework.web.client.RestTemplate;  
      
      
    /** 
     * 远程使用的RestTemplatebean,与服务间调用区分开来 
     */  
    @Configuration  
    public class RestTemplateConfig {  
      
        @Bean("remoteRestTemplate")  
        public RestTemplate remoteRestTemplate() {  
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();  
            factory.setReadTimeout(180000);  
            factory.setConnectTimeout(8000);  
            return new RestTemplate(factory);  
        }  
      
    }  
    
    import com.codahale.metrics.*;  
    import com.netflix.appinfo.InstanceInfo;  
    import com.zaxxer.hikari.HikariDataSource;  
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.beans.factory.annotation.Qualifier;  
    import org.springframework.cloud.client.ServiceInstance;  
    import org.springframework.cloud.client.discovery.DiscoveryClient;  
    import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient;  
    import org.springframework.web.bind.annotation.GetMapping;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RestController;  
    import org.springframework.web.client.RestTemplate;  
      
    import javax.sql.DataSource;  
    import java.util.List;  
    import java.util.Map;  
    import java.util.SortedMap;  
    import java.util.TreeMap;  
      
      
    @RestController  
    @RequestMapping("hikariCpStatsController")  
    public class HikariCpStatsController {  
    private static final String SERVICE_NAME ="xiaoniu";  
        @Autowired  
        private DataSource dataSource;  
      
        @Autowired  
        private DiscoveryClient discoveryClient;  
      
        @Qualifier("remoteRestTemplate")  
        @Autowired  
        private RestTemplate restTemplate;  
      
        @GetMapping("poolStatsHa")  
        public TreeMap<String, Object> poolStatsHa() {  
            MetricRegistry metricRegistry = null;  
            if (dataSource instanceof HikariDataSource) {  
                metricRegistry = (MetricRegistry) ((HikariDataSource) dataSource).getMetricRegistry();  
            }  
            if (metricRegistry == null)  
                return null;  
            TreeMap<String, Object> dataAll = new TreeMap<>();  
            // 节点的信息  
            List<ServiceInstance> instances = discoveryClient.getInstances(SERVICE_NAME);  
            for (ServiceInstance instance : instances) {  
                InstanceInfo instanceInfo = ((EurekaDiscoveryClient.EurekaServiceInstance) instance).getInstanceInfo();  
                TreeMap data = restTemplate.getForObject(instance.getUri().toString() + "/hikariCpStatsController/poolStats", TreeMap.class);  
                dataAll.put(instanceInfo.getInstanceId(), data);  
            }  
            return dataAll;  
        }  
      
        @GetMapping("poolStats")  
        public TreeMap<String, Object> poolStats() {  
            MetricRegistry metricRegistry = null;  
            if (dataSource instanceof HikariDataSource) {  
                metricRegistry = (MetricRegistry) ((HikariDataSource) dataSource).getMetricRegistry();  
            }  
            if (metricRegistry == null)  
                return null;  
      
            TreeMap<String, Object> data = new TreeMap<>();  
      
            SortedMap<String, Gauge> gauges = metricRegistry.getGauges();  
            for (Map.Entry<String, Gauge> gaugeEntry : gauges.entrySet()) {  
                String key = gaugeEntry.getKey();  
                Gauge value = gaugeEntry.getValue();  
                data.put(key, value.getValue());  
      
            }  
            SortedMap<String, Timer> timers = metricRegistry.getTimers();  
            for (Map.Entry<String, Timer> timerEntry : timers.entrySet()) {  
                String key = timerEntry.getKey();  
                Timer value = timerEntry.getValue();  
                data.put(key, "获取连接时99%线程等待的纳秒=" + value.getSnapshot().get99thPercentile());  
            }  
            SortedMap<String, Meter> meters = metricRegistry.getMeters();  
            for (Map.Entry<String, Meter> meterEntry : meters.entrySet()) {  
                String key = meterEntry.getKey();  
                Meter value = meterEntry.getValue();  
                data.put(key, "count=" + value.getCount());  
            }  
            SortedMap<String, Histogram> histograms = metricRegistry.getHistograms();  
            for (Map.Entry<String, Histogram> histogramEntry : histograms.entrySet()) {  
                String key = histogramEntry.getKey();  
                Histogram value = histogramEntry.getValue();  
                data.put(key, "99%连接线程使用的毫秒=" + value.getSnapshot().get99thPercentile());  
            }  
            return data;  
        }  
    }  
    

    在此大功告成

    参考// see detail https://github.com/brettwooldridge/HikariCP/wiki/Dropwizard-Metrics

  • 相关阅读:
    Ubuntu 17 安装sublime
    ubuntu17 设置python3为默认及一些库的安装
    Java中内存分析(一)
    我的学习JavaEE路线
    我爱学习……
    HDU 4602
    K-special Tables
    Gym 100712A - Who Is The Winner
    UVA 1583
    水题 UVA 1586
  • 原文地址:https://www.cnblogs.com/li-yg/p/13891550.html
Copyright © 2011-2022 走看看