jmeter压测

pull/19/head^2
qiurunze 2018-12-22 14:31:51 +08:00
parent 9c26d6f579
commit e230b55c4e
13 changed files with 313 additions and 16 deletions

View File

@ -40,7 +40,7 @@
| ID | Problem | Article |
| --- | --- | :--- |
| 000 |如何解决卖超问题 | [解决思路](/docs/code-solve.md) |
| 001 |如何对本项目进行jmeter压测 | [解决思路](/docs/code-solve.md) |
| 001 |如何对本项目进行jmeter压测 | [解决思路](/docs/jemter-solve.md) |
| 003 |全局异常处理拦截 |[解决思路](/docs/code-solve.md) |
| 003 |页面级缓存thymeleafViewResolver |[解决思路](/docs/code-solve.md) |
| 004 |对象级缓存redis🙋🐓 |[解决思路](/docs/code-solve.md) |

48
docs/jemter-solve.md Normal file
View File

@ -0,0 +1,48 @@
### 如何利用jmeter进行压测
有问题或者宝贵意见联系我的QQ,非常希望你的加入!
>目标 希望大家仔细研究redis.conf配置文件-本文很多基础的一带而过)
1.如何对秒杀生成大数据量对应的用户id和token来进行压测
2.利用jmeter进行接口压测
我这个版本只是简单的测试,你仍然需要把一些接口安全的放开或者自己写一个没有安全性防刷一类的接口测试性能
如果有疑问或者你不懂的地方请联系我!
#### 1 利用jmeter进行接口压测 jmeter3.0 jdk1.7 版本以上需1.8 版本在tools里面
**秒杀生成大数据量对应的用户id和token**
在后端写模拟前端请求计算出不同的用户对应的token 在UserUtil类里面
生成文件格式:
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter4.png)
代码类:
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter2.png)
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter3.png)
利用这个类可以生成大数据量的userId和token当前也可以自己改装生成你想要的
**利用jmeter进行接口压测**
1.点击右键生成线程组一类的
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter5.png)
2.右键线程组选择配置原件并定义http默认值
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter6.png)
3.右键监听器可以生成聚合报告等一类的
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter7.png)
4.右键线程组添加sampler 添加请求http请求具体情况更具实际的来
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter9.png)
5.右键线程组添加CSV DATA Set Config 设置用户参数和token 把生成的路径引进来
![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter8.png)

View File

@ -4,10 +4,10 @@
>目标 希望大家仔细研究redis.conf配置文件-本文很多基础的一带而过)
2.redis分布式锁,zk分布式锁,lua脚本限流,lua分布式锁
3.redis持久化策略
4.redis集群
5.redis的简单操练
1.redis分布式锁,zk分布式锁,lua脚本限流,lua分布式锁
2.redis持久化策略
3.redis集群
4.redis的简单操练
整理大部分常用的场景与使用,如果有疑问或者你不懂的地方请联系我!
#### 1 redis分布式锁

View File

@ -37,4 +37,13 @@ public class LoginController {
userService.login(response, loginVo);
return result;
}
@RequestMapping("/create_token")
@ResponseBody
public String createToken(HttpServletResponse response, @Valid LoginVo loginVo) {
logger.info(loginVo.toString());
String token = userService.createToken(response, loginVo);
return token;
}
}

View File

@ -62,11 +62,11 @@ public class MiaoshaController implements InitializingBean {
* 5000 * 10
* get post get     post
*/
@AccessLimit(seconds = 5, maxCount = 5, needLogin = true)
@RequestMapping(value = "/{path}/do_miaosha", method = RequestMethod.POST)
// @AccessLimit(seconds = 5, maxCount = 5, needLogin = true)
@RequestMapping(value = "/do_miaosha")
@ResponseBody
public ResultGeekQ<Integer> miaosha(Model model, MiaoshaUser user,
@RequestParam("goodsId") long goodsId, @PathVariable("path") String path) {
public ResultGeekQ<Integer> miaosha(Model model, MiaoshaUser user, @PathVariable("path") String path,
@RequestParam("goodsId") long goodsId) {
ResultGeekQ<Integer> result = ResultGeekQ.build();
if (user == null) {
@ -89,7 +89,7 @@ public class MiaoshaController implements InitializingBean {
// }
//是否已经秒杀到
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(Long.valueOf(user.getNickname()), goodsId);
if (order != null) {
result.withError(REPEATE_MIAOSHA.getCode(), REPEATE_MIAOSHA.getMessage());
return result;
@ -131,7 +131,7 @@ public class MiaoshaController implements InitializingBean {
return result;
}
model.addAttribute("user", user);
Long miaoshaResult = miaoshaService.getMiaoshaResult(user.getId(), goodsId);
Long miaoshaResult = miaoshaService.getMiaoshaResult(Long.valueOf(user.getNickname()), goodsId);
result.setData(miaoshaResult);
return result;
}

View File

@ -9,8 +9,8 @@ import java.util.List;
@Mapper
public interface OrderDao {
@Select("select * from miaosha_order where user_id=#{userId} and goods_id=#{goodsId}")
public MiaoshaOrder getMiaoshaOrderByUserIdGoodsId(@Param("userId") long userId, @Param("goodsId") long goodsId);
@Select("select * from miaosha_order where user_id=#{userNickName} and goods_id=#{goodsId}")
public MiaoshaOrder getMiaoshaOrderByUserIdGoodsId(@Param("userNickName") long userNickName, @Param("goodsId") long goodsId);
@Insert("insert into order_info(user_id, goods_id, goods_name, goods_count, goods_price, order_channel, status, create_date)values("
+ "#{userId}, #{goodsId}, #{goodsName}, #{goodsCount}, #{goodsPrice}, #{orderChannel},#{status},#{createDate} )")

View File

@ -129,6 +129,33 @@ public class MiaoShaUserService {
addCookie(response, token, user);
return true ;
}
public String createToken(HttpServletResponse response , LoginVo loginVo) {
if(loginVo ==null){
throw new GlobleException(SYSTEM_ERROR);
}
String mobile =loginVo.getMobile();
String password =loginVo.getPassword();
MiaoshaUser user = getByNickName(mobile);
if(user == null) {
throw new GlobleException(MOBILE_NOT_EXIST);
}
String dbPass = user.getPassword();
String saltDb = user.getSalt();
String calcPass = MD5Utils.formPassToDBPass(password,saltDb);
if(!calcPass.equals(dbPass)){
throw new GlobleException(PASSWORD_ERROR);
}
//生成cookie 将session返回游览器 分布式session
String token= UUIDUtil.uuid();
addCookie(response, token, user);
return token ;
}
private void addCookie(HttpServletResponse response, String token, MiaoshaUser user) {
redisService.set(MiaoShaUserKey.token, token, user);
Cookie cookie = new Cookie(COOKIE_NAME_TOKEN, token);

View File

@ -53,7 +53,7 @@ public class OrderService {
miaoshaOrder.setOrderId(orderInfo.getId());
miaoshaOrder.setUserId(user.getId());
orderDao.insertMiaoshaOrder(miaoshaOrder);
redisService.set(OrderKey.getMiaoshaOrderByUidGid,""+user.getId()+"_"+goods.getId(),miaoshaOrder) ;
redisService.set(OrderKey.getMiaoshaOrderByUidGid,""+user.getNickname()+"_"+goods.getId(),miaoshaOrder) ;
return orderInfo;
}

View File

@ -0,0 +1,31 @@
package com.geekq.miaosha.utils;
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);
}
}

View File

@ -0,0 +1,44 @@
package com.geekq.miaosha.utils;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @author 605162215@qq.com
*
* @date 2018131 4:32:40<br/>
*/
public class HttpUtil {
public static void main(String[] args) throws Exception{
for(int i=0;i<10;i++) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
for(int i=0;i<10;i++) {
URL url = new URL("http://192.168.220.130/index.html");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
InputStream in = conn.getInputStream();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while((len = in.read(buff)) >= 0) {
bout.write(buff, 0, len);
}
in.close();
bout.close();
byte[] response = bout.toByteArray();
System.out.println(new String(response, "UTF-8"));
Thread.sleep(3000);
}
}catch(Exception e) {
}
}
});
t.start();
}
}
}

View File

@ -0,0 +1,36 @@
package com.geekq.miaosha.utils;
import org.apache.commons.codec.digest.DigestUtils;
public class MD5Util {
public static String md5(String src) {
return DigestUtils.md5Hex(src);
}
private static final String salt = "1a2b3c4d";
public static String inputPassToFormPass(String inputPass) {
String str = ""+salt.charAt(0)+salt.charAt(2) + inputPass +salt.charAt(5) + salt.charAt(4);
System.out.println(str);
return md5(str);
}
public static String formPassToDBPass(String formPass, String salt) {
String str = ""+salt.charAt(0)+salt.charAt(2) + formPass +salt.charAt(5) + salt.charAt(4);
return md5(str);
}
public static String inputPassToDbPass(String inputPass, String saltDB) {
String formPass = inputPassToFormPass(inputPass);
String dbPass = formPassToDBPass(formPass, saltDB);
return dbPass;
}
public static void main(String[] args) {
System.out.println(inputPassToFormPass("123456"));//d3b1294a61a07da9b49b6e22b2cbd7f9
// System.out.println(formPassToDBPass(inputPassToFormPass("123456"), "1a2b3c4d"));
// System.out.println(inputPassToDbPass("123456", "1a2b3c4d"));//b7797cce01b4b131b433b6acf4add449
}
}

View File

@ -0,0 +1,102 @@
package com.geekq.miaosha.utils;
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.geekq.miaosha.domain.MiaoshaUser;
public class UserUtil {
private static void createUser(int count) throws Exception{
List<MiaoshaUser> users = new ArrayList<MiaoshaUser>(count);
//生成用户
for(int i=0;i<count;i++) {
MiaoshaUser user = new MiaoshaUser();
user.setId(100L+i);
user.setLoginCount(1);
user.setNickname(String.valueOf(13000000000L+i));
user.setRegisterDate(new Date());
user.setSalt("1a2b3c");
user.setPassword(MD5Util.inputPassToDbPass("123456", user.getSalt()));
users.add(user);
}
System.out.println("create user");
//插入数据库
Connection conn = DBUtil.getConn();
String sql = "insert into miaosha_user(login_count, nickname, register_date, salt, password, id)values(?,?,?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
for(int i=0;i<users.size();i++) {
MiaoshaUser 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/create_token";
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++) {
MiaoshaUser 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.getNickname()+"&password="+MD5Util.inputPassToFormPass("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.getNickname()+","+response;
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(3);
}
}

View File

@ -20,7 +20,7 @@ mybatis.config-locations=classpath:mybatis/config.xml
#datasource
spring.datasource.url=jdbc:mysql://39.107.245.253:3306/miaosha?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=XXXX
spring.datasource.password=nihaoma
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#druid
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
@ -49,7 +49,7 @@ spring.resources.static-locations=classpath:/static/
redis.host=39.107.245.253
redis.port=6379
redis.timeout=100
redis.password=xxxx
redis.password=youxin11
redis.poolMaxTotal=1000
redis.poolMaxIdle=500
redis.poolMaxWait=500