只做各种IO方式的横向比较,故不列具体机器规格
一、 服务端源码
TimeServer.class
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TimeServer {
private static ExecutorService executor = new ThreadPoolExecutor(10, 10, 120L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10000));
public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
}
}
try (ServerSocket server = new ServerSocket(port);) {
System.out.println("The time server is start in port: " + port);
Socket socket = null;
while (true) {
socket = server.accept();
executor.execute(new TimeServerHandler(socket));
}
}
}
}
TimeServerHandler.class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
public class TimeServerHandler implements Runnable {
private Socket socket;
public TimeServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true);){
String currentTime = null;
String body = null;
while (true) {
body = in.readLine();
if (body == null) {
break;
}
System.out.println("The time server receive order : " + body);
currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(
System.currentTimeMillis()).toString() : "BAD ORDER";
out.println(currentTime);
}
} catch (Exception e) {
try {
this.socket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
二、Jemeter 压测结果
5线程
Jconsole结果
Jemeter吞吐量
CPU占用率18.6%,吞吐量53611。
10线程
Jconsole结果
Jemeter吞吐量
CPU占用率18.6%,吞吐量66699。
20线程
Jconsole结果
Jemeter吞吐量
CPU占用率19.2%,吞吐量63006。
对于伪异步IO的线程池使用,优缺点都是比较明显的,由于线程池固定10个线程,Jemeter 5线程压测时吞吐量更高,因为服务端起了超过5个线程进行处理,10线程压测时差别不大,20线程压测吞吐量反而不如10线程,还产生了大量失败的请求,因为服务端处理能力不足。