同步servlet VS 异步servlet

BIO、NIO、AIO三者的比较

消息时的系统通信,通常基于网络协议实现。常见的协议包括TCP/IP,UDP/IP。

TCP/IP等协议用于数据传输,但要完成通信,还需要对数据进行处理。例如读取和写入数据。

I/O可以分为两种:同步IO和异步IO,同步I/O最常见的是 BIO(Blocking IO)、NIO(Non-Blocking IO)

  • BIO:是当发起I/O的读或写操作时,均为阻塞方式,直到应用程序读到了流或者将流写入数据。

  • NIO:基于事件驱动思想,常采用reactor(反应器)模式。当发起 IO请求时,应用程序是非阻塞的。当SOCKET有流可读或写的时候,由操作系统通知应用程序,应用程序再将流读取到缓冲区或者写入系统。

  • AIO:同样基于事件驱动的思想,通常采用Proactor(前摄器模式)实现。在进行I/O操作时,直接调用API的read或write,这两种方法均为异步。对于读操作,操作系统将数据读到缓冲区,并通知应用程序,对于写操作,操作系统将write方法传递的流写入并主动通知应用程序。它节省了NIO中遍历事件通知队列的代价。

这里注意比较NIO和AIO的不同,AIO是操作系统完成IO并通知应用程序,NIO是操作系统通知应用程序,由应用程序完成。

spring boot tomcat 默认线程100个,tomcat 9

spring boot 使用servlet 方式


@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ServletComponentScan
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

异步servlet


image.png

@WebServlet(urlPatterns = "/async", asyncSupported = true)
@Slf4j
public class ASyncServlet extends HttpServlet {
    Executor poolExecutor = Executors.newFixedThreadPool(300);
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        AsyncContext asyncContext = req.startAsync();
        CompletableFuture.runAsync(() -> {
            ServletRequest request = asyncContext.getRequest();
            ServletResponse response = asyncContext.getResponse();
            try {
                TimeUnit.SECONDS.sleep(3);
                PrintWriter writer = response.getWriter();
                writer.print("hello async");
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            asyncContext.complete();
        }, poolExecutor);
    }
}

异步servlet

ab -c 300 -n 1000 http://localhost:8080/async
 

Server Software:
Server Hostname:        localhost
Server Port:            8080

Document Path:          /async
Document Length:        11 bytes

Concurrency Level:      300
Time taken for tests:   15.186 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      104000 bytes
HTML transferred:       11000 bytes
Requests per second:    65.85 [#/sec] (mean)
Time per request:       4555.704 [ms] (mean)
Time per request:       15.186 [ms] (mean, across all concurrent requests)
Transfer rate:          6.69 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0      10
Processing:  3000 3018  23.7   3005    3233
Waiting:     3000 3012  17.2   3003    3063
Total:       3000 3019  23.8   3006    3234

 

同步servlet

@WebServlet(urlPatterns = "/sync")
@Slf4j
public class SyncServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        PrintWriter writer = resp.getWriter();
        writer.print("hello async");
        writer.close();
    }
}

ab -c 300 -n 1000 http://localhost:8080/sync
 

Server Software:
Server Hostname:        localhost
Server Port:            8080

Document Path:          /sync
Document Length:        11 bytes

Concurrency Level:      300
Time taken for tests:   18.118 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      104000 bytes
HTML transferred:       11000 bytes
Requests per second:    55.19 [#/sec] (mean)
Time per request:       5435.342 [ms] (mean)
Time per request:       18.118 [ms] (mean, across all concurrent requests)
Transfer rate:          5.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.5      1       2
Processing:  3002 4195 1401.3   3071    5942
Waiting:     3000 4188 1404.7   3059    5942
Total:       3003 4196 1401.4   3072    5942

 

异步模式下使用 300个处理线程在跑分生超出同步模式不少

你可能感兴趣的:(同步servlet VS 异步servlet)