Java秒杀实战 JMeter压测

Posted sharpest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java秒杀实战 JMeter压测相关的知识,希望对你有一定的参考价值。

转自:https://blog.csdn.net/qq_41305266/article/details/81071278、

一、JMeter入门

下载链接 http://jmeter.apache.org/download_jmeter.cgi

 技术图片

 

添加线程组

 技术图片

 

 技术图片

 

设置http请求默认值

 

 技术图片

技术图片

 

添加待压测的http请求

技术图片

技术图片

 

添加聚合报告监听器

 技术图片

 

启动测试

 技术图片

 

1000个线程,循环10次,即10000个请求

 技术图片

技术图片

 

 

 

二、redis 压测

1. redis-benchmark -h 127.0.0.1 -p 6379  -c 100 -n 100000 

100个并发连接,100000个请求

 技术图片

 

2. redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100

100 个字节

 技术图片

 

3. redis-benchmark -t set,lpush -q -n 100000

 技术图片

 

4.redis-benchmark -n 100000 -q script load "redis.call(‘set‘,‘foo‘,‘set‘)"

 技术图片

 

三、SpringBoot打war包

pom添加依赖

<!-- provided表示 编译时依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<build>
<finalName>$project.artifactId</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
启动类gen更改如下:

package com.wings.seckill;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class MainApplication extends SpringBootServletInitializer

public static void main(String[] args)
SpringApplication.run(MainApplication.class, args);



@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
return builder.sources(MainApplication.class);


三、JMeter命令行

总体思路:

1.在windows上录好jmx;

2.命令行:sh jmeter.sh -n -t XXX.jmx -l result.jtl

3.把result.jtl导入到jmeter

pom文件去掉war包相关依赖及插件,添加以下插件

<build>
<finalName>$project.artifactId</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
入口类改回最清爽模式

package com.wings.seckill;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class MainApplication

public static void main(String[] args)
SpringApplication.run(MainApplication.class, args);



批量新增用户相关辅助类

package com.wings.seckill.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class DBUtil

private static Properties props;

static
try
InputStream in = DBUtil.class.getClassLoader().getResourceAsStream("application.properties");
props = new Properties();
props.load(in);
in.close();
catch(Exception e)
e.printStackTrace();



public static Connection getConn() throws Exception
String url = props.getProperty("spring.datasource.url");
String username = props.getProperty("spring.datasource.username");
String password = props.getProperty("spring.datasource.password");
String driver = props.getProperty("spring.datasource.driver-class-name");
Class.forName(driver);
return DriverManager.getConnection(url,username, password);


package com.wings.seckill.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wings.seckill.domain.SeckillUser;

public class UserUtil

private static void createUser(int count) throws Exception
List<SeckillUser> users = new ArrayList<SeckillUser>(count);
// 生成用户
for (int i = 0; i < count; i++)
SeckillUser user = new SeckillUser();
user.setId(13000000000L + i);
user.setLoginCount(1);
user.setNickname("user" + i);
user.setRegisterDate(new Date());
user.setSalt("1a2b3c");
user.setPassword(Md5Util.inputPass2DbPass("123456", user.getSalt()));
users.add(user);

System.out.println("create user");
/* // 插入数据库
Connection conn = DBUtil.getConn();
String sql = "insert into seckill_user(login_count, nickname, register_date, salt, password, id)values(?,?,?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
for (int i = 0; i < users.size(); i++)
SeckillUser user = users.get(i);
pstmt.setInt(1, user.getLoginCount());
pstmt.setString(2, user.getNickname());
pstmt.setTimestamp(3, new Timestamp(user.getRegisterDate().getTime()));
pstmt.setString(4, user.getSalt());
pstmt.setString(5, user.getPassword());
pstmt.setLong(6, user.getId());
pstmt.addBatch();

pstmt.executeBatch();
pstmt.close();
conn.close();
System.out.println("insert to db");*/
// 登录,生成token
String urlString = "http://localhost:8080/login/do_login";
File file = new File("D:/tokens.txt");
if (file.exists())
file.delete();

RandomAccessFile raf = new RandomAccessFile(file, "rw");
file.createNewFile();
raf.seek(0);
for (int i = 0; i < users.size(); i++)
SeckillUser user = users.get(i);
URL url = new URL(urlString);
HttpURLConnection co = (HttpURLConnection) url.openConnection();
co.setRequestMethod("POST");
co.setDoOutput(true);
OutputStream out = co.getOutputStream();
String params = "mobile=" + user.getId() + "&password=" + Md5Util.inputPass2FormPass("123456");
out.write(params.getBytes());
out.flush();
InputStream inputStream = co.getInputStream();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int len = 0;
while ((len = inputStream.read(buff)) >= 0)
bout.write(buff, 0, len);

inputStream.close();
bout.close();
String response = new String(bout.toByteArray());
JSONObject jo = JSON.parseObject(response);
String token = jo.getString("data");
System.out.println("create token : " + user.getId());

String row = user.getId() + "," + token;
raf.seek(raf.length());
raf.write(row.getBytes());
raf.write("\\r\\n".getBytes());
System.out.println("write to file : " + user.getId());

raf.close();

System.out.println("over");


public static void main(String[] args) throws Exception
createUser(5000);


JMeter添加CSV文件

 技术图片

 

 技术图片

 

 技术图片

 

优化前结果:

1000 * 10

QPS:109

 

 

出现超卖现象:

技术图片

 

以上是关于Java秒杀实战 JMeter压测的主要内容,如果未能解决你的问题,请参考以下文章

秒杀——JMeter 自定义变量

电商性能测试实战 | JMeter 插件 Ultimate Thread Group 完成梯度递增场景的压测

Jmeter性能实战--实现接口压测完整流程(一)

JMeter简单的接口压测实战

性能测试实战 | 修改 JMeter 源码,定制化聚合压测报告

Jmeter4.0压测实战