1.Jmeter基本使用
为了验证秒杀优化的效果,我们使用了Jmeter进行压力测试。这里就简单总结下Jmeter的基本使用。
-
首先添加一个测试计划,点击File->New。右键Test Plan,Add->Threads->Thread Group添加线程组。在这里,我们设置线程个数为5000,0s内创建好,即立即创建并发起请求。
-
添加一个默认请求,设置请求协议 ip 端口等基本信息,这样后面的请求就可以不用再输入这些参数了。右键Thread Group,Add->Config Element->Http Request Defaults
-
添加一个聚合报告,用于展示测试结果。右键Thread Group,Add->Listener->Aggregate Report
-
添加一个待测试的Http请求。右键Thread Group,Add->Sampler->Http Request。填入method path等基本信息,由于之前已经建了一个默认的请求,所以ip 端口等信息就不需要重复输入了。
-
点击Start(即顶部的绿色箭头),就可以开始测试了
2.模拟登录用户
因为我们的请求都要求在登录的情况下才能进行,否则拦截器会直接重定向到登录页面。所以需要在请求时设置cookie信息,模拟已登录的用户。
- 首先向MySQL插入5000个用户,并使用这5000个用户登录系统,将生成的JSESSIONID写入文件。
/**
* 准备Jmeter测试需要的数据
*
*/
@Controller
public class BeforeTest {
@Autowired
UserService userService;
/**
* 生成用户,并插入数据库
*
* @param count
* @throws Exception
*/
@RequestMapping("/prepareUser")
@ResponseBody
public String prepareUser(int count) throws Exception {
List<User> users = new ArrayList<User>(count);
// 生成用户
for (int i = 1; i <= count; i++) {
User user = new User();
user.setId(i);
user.setName("user" + i);
user.setPassword("admin");
users.add(user);
}
System.out.println("create user");
// 插入数据库
userService.insert(users);
System.out.println("insert to db");
return "success";
}
/**
* 用数据库中的所有用户执行登录,并将sessionId存入文件中
* @param users
* @param session
* @throws IOException
*/
@RequestMapping("/prepareLoginUser")
@ResponseBody
public String prepareLoginUser(HttpSession session) throws IOException {
List<User> users = userService.findAllUser();
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++) {
User user = users.get(i);
URL url = new URL("http://localhost:8080/prepareLogin");
HttpURLConnection co = (HttpURLConnection)url.openConnection();
co.setRequestMethod("POST");
co.setDoOutput(true);
OutputStream out = co.getOutputStream();
String params = "name="+user.getName()+"&password="+user.getPassword();
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 sessionId = new String(bout.toByteArray());
raf.seek(raf.length());
raf.write(sessionId.getBytes());
raf.write("\r\n".getBytes());
}
raf.close();
return "success";
}
@RequestMapping("/prepareLogin")
@ResponseBody
public String prepareLogin(HttpServletRequest request,HttpSession session) {
User paramUser = new User(request.getParameter("name"), request.getParameter("password"));
User dbUser = userService.login(paramUser);
if(dbUser != null) {
//登录成功,将用户放入session
session.setAttribute("user", dbUser);
}
return session.getId();
}
}
-
在Jmeter中添加CSV配置文件,指向上一步生成的配置文件。Thread Group右键,Add->Config Element->CSV Data Set Config。设置变量名,后面会通过该变量名来引用;设置变量分割符,当然我们这里只有一个变量。
-
为请求添加cookie信息,右键Thread Group,Add->Config Element->Http Cookie Manager。设置cookie的名字;值为上一步骤的变量名的引用,像EL表达式一样,也是${};设置domain path。
这样在所有请求中,都会携带已登录用户的cookie信息。
完整的jmeter配置文件,可以参看bargainsDash.jmx
附:所有代码在github上