Springboot中的NIO模式
背景
SpringBoot默认使用了tomcat来做为webserver,对应大量请求响应慢的接口时,由于背后是同步IO,会导致整体吞吐下降。
比如:有一个api/slow
接口,响应需要8秒。
使用客户端进行请求时,100个线程请求api/slow接口。会出现,大量请求耗时 > 8秒,可能为16秒,或者24秒。
在此时,再加一个快接口health
接口,正常响应为10ms。但是请求此health
接口时,也能看到大量响应 >= 4秒的。
原因
slow
操作,会将所有的child
线程都占满。
解决方法
在 channelRead0
中,将慢任务,放在线程池中执行,以保证不阻碍child
线程。
示例如下:
// 异步执行,按uri隔离
nettyHttpServices.get(uri).execute(() -> {
NettyHttpHandler handler = nettyHttpHandlerMap.get(uri);
if (handler == null) {
log.error("invalid uri = {}", uri);
ctx.close();
return;
}
String response = handler.handle(httpContent);
writeResponse(ctx, trailer, response);
});