1. 程式人生 > 其它 >RDS for MySQL併發效能測試

RDS for MySQL併發效能測試

最近由於工作需要,需要對阿里雲資料庫-RDS for MySQL進行效能測試,通過MySQL自帶的mysqlslap工具可以進行併發效能測試,但是輸出顯示總感覺有問題,所以就萌生想法自己開發程式碼通過JDBC連線RDS,測試RDS的併發效能。本文是自己寫的Java程式,模擬mysqlslap進行併發測試。

RDS for MySQL版本:MySQL8.0

1、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> <groupId>org.example</groupId> <artifactId>RdsConcurrencyTest</artifactId> <
version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>
mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <minimizeJar>false</minimizeJar> <shadedArtifactAttached>true</shadedArtifactAttached> <artifactSet> <includes> <!-- Include here the dependencies you want to be packed in your fat jar --> <include>*:*</include> </includes> </artifactSet> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> <exclude>**/log4j.properties</exclude> </excludes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.mysql.test.RdsConcurrencyTest</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>reference.conf</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource> META-INF/ </resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.3.2</version> <executions> <execution> <id>scala-compile-first</id> <phase>process-resources</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>scala-test-compile-first</id> <phase>process-test-resources</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

2、工具類

package com.mysql.test;

import java.sql.*;
import java.util.List;

public class DBUtil implements Runnable{

    private final String host;
    private final String port;
    private final String user;
    private final String password;
    private final String database;
    private final String sql;
    private   String url = null;
    private  long  costTime;
    private List<Long> list;

    public long getCostTime() {
        return costTime;
    }

    public DBUtil(String host1,String port1,String database1,String user1,String password1,String sql1,List<Long> list){
        this.host = host1;
        this.port = port1;
        this.user = user1;
        this.password = password1;
        this.database = database1;
        this.sql = sql1;
        this.list = list;
    }

    //獲取Connection連線物件的方法,使用static方便之後在其他類中呼叫
    public  Connection getConn() {
        Connection conn = null;
        try {
            String name = "com.mysql.cj.jdbc.Driver";
            Class.forName(name);
            conn = DriverManager.getConnection(url, user, password);//獲取連線
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return conn;
    }

    //關閉資源的方法
    public  void close(ResultSet rs,PreparedStatement ps,Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void run() {
        // 開始時間
        long startTime = 0;
        startTime = System.currentTimeMillis();

        url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT";
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection myConn = getConn();
        try {
            ps = myConn.prepareStatement(sql);
            rs = ps.executeQuery();

            // 結束時間
            long endTime = System.currentTimeMillis();
            costTime = endTime - startTime;
            list.add(costTime);

            int  fieldCount = rs.getMetaData().getColumnCount();
            while (rs.next()) {
                int i;
                StringBuilder result = new StringBuilder();
                for (i=1;i<=fieldCount;i++){
                    result.append(rs.getString(i)).append(",");
                }
                //System.out.println(result);
            }
        } catch (SQLException throwable) {
            throwable.printStackTrace();
        } finally {
            close(rs,ps,myConn);
        }


    }
}

3、併發測試類

package com.mysql.test;

import java.sql.SQLOutput;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RdsConcurrencyTest {

    public static  String host = null;
    public static  String port = null;
    public static  String user = null;
    public static  String password = null;
    public static  String database = null;
    public static  String sql = null;
    public static  String concurrent = null;

    // 處理Main方法傳入的引數
    private static boolean parseArgs(String[] args) {
        for(int i = 0; i < args.length;) {
            if (args[i].equals("--host")) {
                host = args[i+1];
                i += 2;
            } else if (args[i].equals("--port")) {
                port = args[i+1];
                i += 2;
            } else if (args[i].equals("--database")) {
                database = args[i+1];
                i += 2;
            } else if (args[i].equals("--user")) {
                user = args[i+1];
                i += 2;
            } else if (args[i].equals("--password")) {
                password = args[i+1];
                i += 2;
            } else if (args[i].equals("--sql")) {
                sql = args[i+1];
                i += 2;
            } else if (args[i].equals("--concurrent")) {
                concurrent = args[i+1];
                i += 2;
            } else {
                return false;
            }
        }
        return true;
    }

    //如果沒有傳參或者傳參錯誤,列印傳參的格式
    private static void printUsage() {
        System.err.println("Usage: RdsConcurrencyTest [options]");
        System.err.println("\t--host\thost ip");
        System.err.println("\t--port\tport");
        System.err.println("\t--database\tdatabase");
        System.err.println("\t--user\tuser");
        System.err.println("\t--password\tpassword");
        System.err.println("\t--sql\tsql");
        System.err.println("\t--concurrent\t[Num]");
    }

    // Main方法入口
    public static void main(String[] args) {
        if (!parseArgs(args)) {
            printUsage();
            System.exit(1);
        }
        if (host == null || port == null || database == null ||
                user == null || password == null || sql == null || concurrent == null) {
            printUsage();
            System.exit(1);
        }

        //開始時間
        Date startDt = new Date();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");

        // 設定併發數(執行緒數)
        int concurrentNum = Integer.parseInt(concurrent);
        ExecutorService executorService = Executors.newFixedThreadPool(concurrentNum);
        DBUtil thread ;
        List<Long> reList = new ArrayList<Long>();
        for(int i = 0; i< concurrentNum; i++)
        {
            thread = new DBUtil(host,port,database,user,password,sql,reList);
            executorService.execute(thread);
        }
        //關閉執行緒池
        executorService.shutdown();

        while (true) {
            //所有的執行緒都結束
            if (executorService.isTerminated()) {
                //結束時間
                Date endDt = new Date();
                long maxTime = Collections.max(reList);
                long minTime = Collections.min(reList);
                long allTime = 0L;
                for(Long cost:reList){
                    allTime += cost;
                }

                long avgTime = allTime/reList.size();

                System.out.println("Milliseconds to run all queries : " + reList);
                System.out.println("Maximum of milliseconds to run all queries : " + maxTime + "ms.");
                System.out.println("Minimum of milliseconds to run all queries : " + minTime + "ms.");
                System.out.println("Average of milliseconds to run all queries : " + avgTime + "ms.");
                System.out.println("Number of concurrent : " + concurrentNum);
                System.out.println("Run begin time : " + ft.format(startDt));
                System.out.println("Run  end  time : " + ft.format(endDt));
                System.out.println("--------------------------------------------------------------------------------");
                break;
            }
        }

    }

}

4、使用編譯好的jar包在ECS上進行測試。