不同模式的性能压测

环境:JDK8、win10,4核8线程

单线程的socket程序

public class HttpServer01 {
    public static void main(String[] args) throws IOException{
        ServerSocket serverSocket = new ServerSocket(8801);
        while (true) {
            try {
                Socket socket = serverSocket.accept();
                service(socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private static void service(Socket socket) {
        try {
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
            printWriter.println("HTTP/1.1 200 OK");
            printWriter.println("Content-Type:text/html;charset=utf-8");
            String body = "hello,nio1";
            printWriter.println("Content-Length:" + body.getBytes().length);
            printWriter.println();
            printWriter.write(body);
            printWriter.close();
            socket.close();
        } catch (IOException e) { // | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

压测:使用sb工具,给40个并发,压60秒。

C:\Users>sb -u http://localhost:8801 -c 40 -N 60
Starting at 2021/7/19 13:02:16
[Press C to stop the test]
143395  (RPS: 2247)
---------------Finished!----------------
Finished at 2021/7/19 13:03:20 (took 00:01:03.9043972)
Status 303:    57964
Status 200:    85432

RPS: 2347.6 (requests/second)
Max: 163ms
Min: 0ms
Avg: 5.2ms

  50%   below 2ms
  60%   below 5ms
  70%   below 7ms
  80%   below 10ms
  90%   below 14ms
  95%   below 19ms
  98%   below 26ms
  99%   below 31ms
99.9%   below 47ms

每个请求一个线程

public class HttpServer02 {
    public static void main(String[] args) throws IOException{
        ServerSocket serverSocket = new ServerSocket(8802);
        while (true) {
            try {
                final Socket socket = serverSocket.accept();
                new Thread(() -> {
                    service(socket);
                }).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private static void service(Socket socket) {
        try {
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
            printWriter.println("HTTP/1.1 200 OK");
            printWriter.println("Content-Type:text/html;charset=utf-8");
            String body = "hello,nio2";
            printWriter.println("Content-Length:" + body.getBytes().length);
            printWriter.println();
            printWriter.write(body);
            printWriter.close();
            socket.close();
        } catch (IOException e) { // | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

压测:使用sb工具,给40个并发,压60秒。

C:\Users>sb -u http://localhost:8802 -c 40 -N 60
Starting at 2021/7/19 13:11:59
[Press C to stop the test]
104055  (RPS: 1630.4)
---------------Finished!----------------
Finished at 2021/7/19 13:13:03 (took 00:01:03.8710839)
Status 200:    92093
Status 303:    11975

RPS: 1704.9 (requests/second)
Max: 88ms
Min: 0ms
Avg: 9ms

  50%   below 7ms
  60%   below 9ms
  70%   below 12ms
  80%   below 15ms
  90%   below 21ms
  95%   below 26ms
  98%   below 32ms
  99%   below 36ms
99.9%   below 50ms

创建固定大小的线程池处理请求

public class HttpServer03 {
    public static void main(String[] args) throws IOException{

        ExecutorService executorService = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors() + 2);
        final ServerSocket serverSocket = new ServerSocket(8803);
        while (true) {
            try {
                final Socket socket = serverSocket.accept();
                executorService.execute(() -> service(socket));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private static void service(Socket socket) {
        try {
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
            printWriter.println("HTTP/1.1 200 OK");
            printWriter.println("Content-Type:text/html;charset=utf-8");
            String body = "hello,nio";
            printWriter.println("Content-Length:" + body.getBytes().length);
            printWriter.println();
            printWriter.write(body);
            printWriter.close();
            socket.close();
        } catch (IOException e) { // | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

压测:使用sb工具,给40个并发,压60秒。

C:\Users>sb -u http://localhost:8803 -c 40 -N 60
Starting at 2021/7/19 13:15:28
[Press C to stop the test]
137776  (RPS: 2157.7)
---------------Finished!----------------
Finished at 2021/7/19 13:16:32 (took 00:01:04.0038139)
Status 200:    73110
Status 303:    64666

RPS: 2251.8 (requests/second)
Max: 158ms
Min: 0ms
Avg: 5.7ms

  50%   below 3ms
  60%   below 6ms
  70%   below 8ms
  80%   below 11ms
  90%   below 15ms
  95%   below 20ms
  98%   below 27ms
  99%   below 32ms
99.9%   below 49ms

小结,socket处理请求是阻塞模式;使用单独线程处理请求,理论上性能会好一些;使用线程池可以避免因频繁创建线程造成的开销。