IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot集群监控—自定义监控Tomcat、Druid集成Grafana -> 正文阅读

[Java知识库]SpringBoot集群监控—自定义监控Tomcat、Druid集成Grafana

接着上篇文章介绍,上篇文章使用了Prometheus+Grafana+AlertManager实现了报警系统,并了解了其中的一些原理。原理就是Prometheus采集了SpringBoot Actuator暴露出的数据,并放到了Grafana做了一个数据可视化。

今天我们单拿出Tomcat和Druid来说,是因为需要一定的配置才能暴露到SpringBoot Actuator

SpringBoot版本:2.3.6.RELEASE web和actuator版本相同

一、监控tomcat

1.项目中Tomcat配置

server:
  tomcat:
    threads:
      max: 500         #设定处理客户请求的线程的最大数目,决定了服务器可以同时响应客户请求的数,默认200
      min-spare: 20    # 初始化线程数,最小空闲线程数,默认是10
    accept-count: 1000 #当所有可以使用的处理请求的线程数都被使用时,可以被放到处理队列中请求数,请求数超过这个数的请求将不予处理,默认100

2.暴露到SpringBoot Actuator

因为SpringBoot已经内置了Tomcat ,需要开启一下配置就可以

server.tomcat.mbeanregistry.enabled=true

因为在上篇文章中发现Grafana的Tomcat板块没有内容,很纳闷,就去官网上找了下答案,发现需要开启一下配置
https://github.com/spring-projects/spring-boot/issues/24503

3.SpringBoot Actuator暴露出来的数据

在这里插入图片描述

4.Grafana展示页面

在这里插入图片描述

二、监控Druid

1.项目中的配置

druid:
 initial-size: 5                                       # 初始化大小
 min-idle: 10                                          # 最小连接数
 max-active: 200                                        # 最大连接数
 max-wait: 60000                                       # 获取连接时的最大等待时间
 min-evictable-idle-time-millis: 300000                # 一个连接在池中最小生存的时间,单位是毫秒
 time-between-eviction-runs-millis: 60000              # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒
 filters: stat                                         # 配置扩展插件:stat-监控统计,log4j-日志,wall-防火墙(防止SQL注入),去掉后,监控界面的sql无法统计   ,wall
 validation-query: SELECT 1                            # 检测连接是否有效的 SQL语句,为空时以下三个配置均无效
 test-on-borrow: true                                  # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能
 test-on-return: true                                  # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能
 test-while-idle: true                                 # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能

2.暴露到SpringBoot Actuator

SpringBoot没有实现暴露Druid数据的方法,所以需要自己实现了。参考下如何暴露Tomcat的数据,在TomcatMetrics类中

public class TomcatMetrics implements MeterBinder, AutoCloseable {

    @Override
    public void bindTo(MeterRegistry registry) {
        registerGlobalRequestMetrics(registry);
        registerServletMetrics(registry);
        registerCacheMetrics(registry);
        registerThreadPoolMetrics(registry);
        registerSessionMetrics(registry);
    }

    private void registerSessionMetrics(MeterRegistry registry) {
    
        Gauge.builder("tomcat.sessions.active.max", manager, Manager::getMaxActive)
                .tags(tags)
                .baseUnit(BaseUnits.SESSIONS)
                .register(registry);

        Gauge.builder("tomcat.sessions.active.current", manager, Manager::getActiveSessions)
                .tags(tags)
                .baseUnit(BaseUnits.SESSIONS)
                .register(registry);

        FunctionCounter.builder("tomcat.sessions.created", manager, Manager::getSessionCounter)
                .tags(tags)
                .baseUnit(BaseUnits.SESSIONS)
                .register(registry);

        FunctionCounter.builder("tomcat.sessions.expired", manager, Manager::getExpiredSessions)
                .tags(tags)
                .baseUnit(BaseUnits.SESSIONS)
                .register(registry);

        FunctionCounter.builder("tomcat.sessions.rejected", manager, Manager::getRejectedSessions)
                .tags(tags)
                .baseUnit(BaseUnits.SESSIONS)
                .register(registry);

        TimeGauge.builder("tomcat.sessions.alive.max", manager, TimeUnit.SECONDS, Manager::getSessionMaxAliveTime)
                .tags(tags)
                .register(registry);
    }
}

可以看出SpringBoot预留了暴露数据的接口MeterBinder,实现该接口中的bindTo方法就可以暴露出数据了

我们模拟一下Tomcat的实现方法,实现Druid的。参考这位大佬的博客

@Slf4j
@Component
public class DruidDataSourceMetrics implements MeterBinder, ApplicationContextAware {
    private ApplicationContext applicationContext;
    
    public boolean collect(MeterRegistry meterRegistry) {
        Map<String, DruidDataSource> datasources = applicationContext.getBeansOfType(DruidDataSource.class);
        if (datasources.values().contains(null)) {
            return false;
        }
        for (Map.Entry<String, DruidDataSource> entry : datasources.entrySet()) {
            Gauge.builder("druid.pool.error.count",()->(entry.getValue().getErrorCount())).tags("datasourcename", entry.getKey()).description("druid pool error count")
                    .register(meterRegistry);
            Gauge.builder("druid.pool.active.connections", () -> (entry.getValue().getActiveCount())).tags("datasourcename", entry.getKey()).description("druid pool active count")
                    .register(meterRegistry);
            Gauge.builder("druid.pool.idle.connections", () -> (entry.getValue().getPoolingCount())).tags("datasourcename", entry.getKey()).description("druid pool idle count")
                    .register(meterRegistry);
            Gauge.builder("druid.pool.wait.connection.thread", () -> (entry.getValue().getWaitThreadCount())).tags("datasourcename", entry.getKey()).description("druid pool wait thread count")
                    .register(meterRegistry);
            Gauge.builder("druid.pool.sum.connections", () -> ((entry.getValue().getPoolingCount() + entry.getValue().getActiveCount()))).tags("datasourcename", entry.getKey()).description("druid pool sum count")
                    .register(meterRegistry);
        }
        return true;
    }

    public void bindTo(MeterRegistry meterRegistry) {
        try {
            Executors.newSingleThreadScheduledExecutor().schedule(() -> {
                while (!collect(meterRegistry)) {
                }
            }, 5, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.warn("druid datasource collected error{}",e);
        }

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

代码实现也比较简单,从IOC容器中拿到DruidDataSource的Bean,使用线程池每隔5s中去获取一下Bean中的属性值使用bindTo方法暴露出去

3.SpringBoot Actuator暴露出的数据

在这里插入图片描述

4.Grafana展示页面

在这里插入图片描述
关注的数据如下

  • acive_connections:这一时刻连接池中活跃的连接有多少
  • idle_connections:这一时刻连接池空闲的连接有多少
  • wait_connection_thread:这一时刻有多少线程处于等待拿数据库连接状态
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 12:04:30  更:2021-10-06 12:05:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:27:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码