最近由于工作需要,需要对阿里云数据库-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上进行测试。

java -jar RdsConcurrencyTest.jar  --host  xxx.mysql.rds.xxx.com.cn  --port 3306 --database lgb_test --user root --password  Root@1234 --sql  "select * from lgb_test" --concurrent 70

RDS for MySQL并发性能测试的更多相关文章

  1. ORM增删改查并发性能测试

    这两天在对一些ORM进行性能测试(涉及SqlSugar.FreeSql.Fast.Framework.Dapper.LiteSql),测试用的是Winform程序,别人第一眼看到我的程序,说,你这测试 ...

  2. ORM增删改查并发性能测试2

    前言 上一篇<ORM增删改查并发性能测试>出现了点小失误,有的输出SQL日志的代码没有禁用,数据库连接字符串可能有问题.统一环境,统一代码后,重新写一篇. 这次重点是并发性能测试,真不是为 ...

  3. 阿里云RDS for MySQL 快速入门——笔记

    1初始化配置 1.1设置白名单 创建RDS实例后,需要设置RDS实例的白名单,以允许外部设备访问该RDS实例.默认的白名单只包含默认IP地址127.0.0.1,表示任何设备均无法访问该RDS实例. 设 ...

  4. 分析一个MySQL并发事务示例

    小结: 1. https://mp.weixin.qq.com/s/hdDl95a6ayVtCoEc3RiLwQ 分析一个MySQL并发事务示例 性能与架构 1月12日   MySQL实战45讲 从原 ...

  5. mysql并发更新

    mysql并发更新 常见方案 乐观锁 select * from tab1 where id = ?; update tab1 set col1 = ? where id = ? and versio ...

  6. rds 与mysql 进行主从同步

    .rds上默认会有server-****,只需要配置从数据库: .从数据库的配置流程: .[mysqld] log-bin = mysql-bin-changelog #要和主库中的名字一样 rela ...

  7. RDS for MySQL 如何使用 Percona Toolkit

    Percona Toolkit 包含多种用于 MySQL 数据库管理的工具. 下面介绍常用的 pt-online-schema-change  和  pt-archiver 搭配 RDS MySQL ...

  8. RDS for MySQL查询缓存 (Query Cache) 的设置和使用

    https://help.aliyun.com/knowledge_detail/41717.html?spm=5176.7841698.2.11.aCvOXJ RDS for MySQL查询缓存 ( ...

  9. 使用sysbench 对mysql进行性能测试

    使用sysbench 对mysql进行性能测试 sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据库的性能测试.目前支持的数据库有My ...

  10. mysql并发量过大造成 update语句更新错误

    mysql并发量过大造成 update语句更新错误 在同一字段的时候更新的时候 如果并发量太大 就会更新错误 这个时候只能用 swoole 消息队列更新

随机推荐

  1. vue实现文件上传功能

    https://www.jb51.net/article/145500.htm Element中的el-upload使用过程中踩的坑 https://www.jianshu.com/p/c837224 ...

  2. 【TouchGFX】visual studio 工程中 SIMULATOR 宏定义位置

  3. 一键部署Docker中间件简单方法-redis为例

    一键部署Docker中间件简单方法-redis为例 背景 想能够快速部署一些中间件. 写文档虽然可以, 但是总会有人问, 能够一键部署应该最好不过. 下载以及导出镜像 docker pull redi ...

  4. [转帖]TiDB 5.1 Write Stalls 应急文档

    https://tidb.net/blog/ac7174dd#4.%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E5%87%BA%E7%8E%B0%E4%BA%86%20w ...

  5. ext4 磁盘扩容

    目录 ext4文件系统磁盘扩容 目标 途径 操作步骤 改变前的现状 操作和改变后的状态 ext4文件系统磁盘扩容 一个磁盘有多个分区,分别创建了物理卷.卷组.逻辑卷.通过虚拟机软件对虚拟机的磁盘/de ...

  6. [转帖]Jmeter正则提取器常用的几种方式

    https://www.cnblogs.com/a00ium/p/10483741.html 使用jmeter的同学都知道,jmeter提供了各种各样的提取器,如jsonpath.Beanshell. ...

  7. [转帖]Linux常用的一些命令,看你知道多少?

    https://zhuanlan.zhihu.com/p/115279009 Linux中命令有很多,而Linux系统中使用命令也是它的一大特点.在Linux系统中使用命令处理问题灵活,高效,所以熟知 ...

  8. [转帖]查询机器序列号--Linux/esxi/windows

    https://www.jianshu.com/p/6abaea79e0c3 Ipmitool--Linux&Esxi&Windows # ipmitool fru list|grep ...

  9. 【转帖】You can now run a GPT-3-level AI model on your laptop, phone, and Raspberry Pi

    https://arstechnica.com/information-technology/2023/03/you-can-now-run-a-gpt-3-level-ai-model-on-you ...

  10. 【转帖】奇淫技巧 | route命令设置网络优先级

    奇淫技巧 | route命令设置网络优先级 https://blog.csdn.net/DynmicResource/article/details/120134745 1. 背景 在生活中的会经常遇 ...