当前位置:   article > 正文

MySQL主从状态监测方案_mysql主从监控

mysql主从监控

说明:本文介绍使用代码监测MySQL主从状态的方案,使用Spring Boot定时器和动态数据源组件(dynamic datasources)

主从搭建

主从搭建,参考拙作:

如下,我已经搭建好了一个MySQL主从,敲下面的命令,可查看从节点状态:

在这里插入图片描述

使用Navicat连接,如下:

在这里插入图片描述

分析&编码

分析

检测从节点的同步状态。同步状态主要看三个指标,分别是:

  • Replica_IO_Running

  • Replica_SQL_Running

  • Read_Source_Log_Pos

前两项分别是Yes,最后这个表示读取主节点binlog的位置(position),需要和主节点的binlog位置一致或者相差不大。

编码

开始编码,使用dynamic datasources组件分别读取主从节点的MySQL状态,比较,再用定时器循环执行。

(pom.xml文件,有些依赖可能不需要,可自行裁剪)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/>
    </parent>

    <groupId>com.hezy</groupId>
    <artifactId>master_slave_detection</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <!--数据库驱动-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--dynamic-datasource-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.6</version>
        </dependency>
    </dependencies>

    <!--打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

(application.yml,配置文件,有些配置可删减)

server:
  port: 8080

# 1.数据源的配置
spring:
  datasource:
    dynamic:
      datasource:
        master:
          url: jdbc:mysql://主数据库IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
          username: admin
          password: MySQL@3306
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave:
          url: jdbc:mysql://从数据库IP:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
          username: admin
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

# 2.mybatis配置
mybatis:
  configuration:
    # 驼峰命名配置
    map-underscore-to-camel-case: true
  # 设置mapper.xml文件所在的路径
  mapper-locations: classpath:mapper/*.xml
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

(Mapper,两个,一个主节点的,一个从节点的)

import com.baomidou.dynamic.datasource.annotation.Master;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.Map;
import java.util.Objects;

@Mapper
@Master
public interface MasterMapper {

    @Select("show master status")
    Map<String, Object> getStatus();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
import com.baomidou.dynamic.datasource.annotation.Slave;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.Map;

@Mapper
@Slave
public interface SlaveMapper {

    @Select("show replica status")
    Map<String, Object> getStatus();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(定时器,每3秒执行一次,监测从节点状态,比较position)

import com.hezy.mapper.MasterMapper;
import com.hezy.mapper.SlaveMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.Map;

@Component
@Log4j2
public class MySQLDetection {

    @Autowired
    private MasterMapper masterMapper;

    @Autowired
    private SlaveMapper slaveMapper;

    @Scheduled(cron = "0/3 * * * * ?")
    public void detection() {
        // 1.获取Master的Position
        Map<String, Object> mapperStatus = masterMapper.getStatus();
        long masterPosition = ((BigInteger) mapperStatus.get("Position")).longValue();

        // 2.获取Slave的Position
        Map<String, Object> slaveStatus = slaveMapper.getStatus();
        long slavePosition = ((BigInteger) slaveStatus.get("Read_Source_Log_Pos")).longValue();

        // 3.判断Slave的[Replica_IO_Running]、[Replica_SQL_Running]配置是否都是YES
        String replicaIoRunning = slaveStatus.get("Replica_IO_Running").toString();
        String replicaSqlRunning = slaveStatus.get("Replica_SQL_Running").toString();
        String lastIoError = slaveStatus.get("Last_IO_Error").toString();
        String lastError = slaveStatus.get("Last_Error").toString();
        if ("Yes".equals(replicaSqlRunning)
                && "Yes".equals(replicaIoRunning)
                && masterPosition - slavePosition < 10) {
            log.info(">>>>>>>Replica_IO_Running:[{}],Replica_SQL_Running:[{}],Master_Position:[{}],Slave_Position:[{}],数据同步正常<<<<<<<",
                    replicaIoRunning, replicaSqlRunning, masterPosition, slavePosition);
        } else {
            log.warn(">>>>>>>Replica_IO_Running:[{}],Replica_SQL_Running:[{}],Master_Position:[{}],Slave_Position:[{}],Last_IO_Error:[{}],Last_Error:[{}]<<<<<<<",
                    replicaIoRunning, replicaSqlRunning, masterPosition, slavePosition, lastIoError, lastError);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

(启动类,加上开启定时注解)

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@MapperScan("com.hezy.mapper")
@EnableScheduling
public class Start {
    public static void main(String[] args) {
        SpringApplication.run(Start.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

测试使用

启动程序,查看控制台信息,目前为止一切正常

在这里插入图片描述

这时,我们手动关闭从节点的同步,查看控制台状态,发现不妙;

在这里插入图片描述

在这里插入图片描述

到这,一个基于代码的MySQL主从状态监测粗糙方案就完成了。如果可以,可以打成一个jar包,上传到服务器上,独立于项目来执行,或者整合到项目中,加上一些短信、邮箱等警报通知功能,发送到项目负责人。

总结

本文介绍了MySQL主从状态监测的一个方案,希望能对大家有启发。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号