Springboot中的NIO模式

  |   0 评论   |   0 浏览

背景

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);
                });

参考

  1. Netty thread model vs long-running taks