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压测的更多相关文章
- (四)Java秒杀项目之JMeter压测
一.JMeter入门压测 1.打开JMeter工具,选中测试计划->右键添加->线程(用户)->线程组,页面中的线程数就是并发数,页面中的Ramp-Up时间(秒)表示通过多长时间启动 ...
- JMeter压测“java.net.BindException: Address already in use: connect”解决方法
之前在windows机上用JMeter压测,50并发下出现大量接口报“java.net.BindException: Address already in use: connect”错误. 从字面的意 ...
- jmeter压测过程中报java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
由于在java中添加了第三方安全策略文件,具体请看https://www.cnblogs.com/mrjade/p/10886378.html,导致在用jmeter压测过程中会遇到以下错误 解决办法: ...
- 【Java分享客栈】未来迈向高级工程师绕不过的技能:JMeter压测
前言 因为工作需要,久违的从自己的有道云笔记中去寻找压测相关的内容,翻开之后发现还不错,温故一遍后顺便整理出来分享给大家. 题外话,工作8年多,有道云笔记不知不觉都6G多了,扫一眼下来尽是云烟过往,竟 ...
- 一文揭秘测试平台中是如何将测试用例一键转化Jmeter压测脚本
接上篇,一键转化将接口测试平台测试用例转化成Jmeter压测脚本思路,这里我首先在java 上面做了一个简单的实验,看看 转化的中间遇到的问题,这里呢,我只是给了一个简单的demo 版本, ...
- 在Linux CentOS上搭建Jmeter压测环境
本文的主要内容是介绍如何在Linux CentOS 服务器上面搭建Jmeter的压测环境整个详细的流程,来满足我们日常工作中对于压力测试环境搭建.压力测试执行过程的需求. 一.首先我们要准备四个东西, ...
- jmeter压测、操作数据库、分布式linux下运行、webservice接口测试、charles抓包
一.jmeter压测 在线程组中设置好,然后添加http请求,t添加聚合报告查看压力测试结果,如图: 一般压测时间10-15分钟,如果是稳定性测试,一般n*12小时,这些并发用户一直在请求. tps: ...
- jmeter 压测duobbo接口,施压客户端自己把自己压死了
jmeter 压测duobbo接口,jmeter代码不合理,导致每执行一次请求,会调用一次消耗内存的实例化.导致越压越慢,请求发不出去.这个时候需要考虑修改代码了. 截图中,tps越来越少. 原来初始 ...
- jmeter压测学习1-window环境准备与案例
前言 最近用jmeter做一些接口的压力测试,记录下使用过程中遇到的一些问题. 在使用window机器做并发压测的时候,发现并发数设置100的时候,会出现报错:java.net.SocketExcep ...
- windows下Jmeter压测端口占用问题(亲测有效)
windows下Jmeter压测端口占用问题 1 报错信息描述 压测的初期,在设置了 150qps/s 的并发数下压测几分钟后 Jmeter 就出现了如下报错. JAVA.NET.BINDEXCEPT ...
随机推荐
- 断句:Store all parameters but the first passed to this function as an array
// Store all parameters but the first passed to this function as an array //除了第一个参数,把调用publish函数时的所有 ...
- 006-log-logback,slf4j+logback
一.概述 Logback作为流行的log4j项目的继承者.它是由log4j的创始人Ceki Gulcu设计的.它是建立在上十年优质日志系统设计经验之上而产生的产品,即logback,它比所有现有的日志 ...
- kafka----简单的脚本命令重点
kafka命令如下: kafka-shell基本命令 在节点hadoop-2,hadoop-3,hadoop-5,启动kafka 启动命令如下 kafka-server-start.sh /usr/l ...
- php开启短标签与<?xml version="1.0" encoding="UTF-8"?>冲突
前两天写了个生成mapsite的源码,想提交到百度和谷歌,在本地测试一点问题都没有,但是在服务器上就显示500错误 最后废了九牛二虎之力,终于可以设置iis直接显示出错信息. 也搞懂了问题所在,默认服 ...
- 升级chrome浏览器导致网站登录功能不能用
笔者开发一个java web项目,低版本的chrome(74以下)可以正常登录,升级到chrome74不能正常登录,登录成功后url会携带一个jsessionid=xxxxxx. 登录成功那个页面有s ...
- array_splice 在数组某位置插入数据
$arr=array('a','b','c','d','e','f','g');//目标数组 $i_arr=array(');//要插入的数组 $n=;//插入的位置 array_splice($ar ...
- linux LVM 系统盘扩容
1.fdisk /dev/sda2.输入n,开始创建新分区3.输入p4.输入w5.mkfs.ext4 /dev/sda36.pvcreate /dev/sda37.vgdisplay 查看VG nam ...
- glew, glee与 gl, glu, glut, glx, glext的区别和关系
GLEW是一个跨平台的C++扩展库,基于OpenGL图形接口.使用OpenGL的朋友都知道,window目前只支持OpenGL1.1的涵数,但 OpenGL现在都发展到2.0以上了,要使用这些Open ...
- 通过bat批处理程序如何实现在多个txt文件后面加上相同的一行文字
通过bat批处理程序如何实现在多个txt文件后面加上相同的一行文字 set/p a=输入要增加的文字 for /f "delims=" %%i in ('dir /b *.txt' ...
- Information retrieval (IR class1)
1. 什么是IR? IR与数据库的区别? 答:数据库是检索结构化的数据,例如关系数据库:而信息检索是检索非结构化/半结构化的数据,例如:一系列的文本.信息检索是属于NLP(自然语言处理)里面最实用的一 ...