You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建原生非阻塞Servlet及实现响应式服务相关问题咨询

问题1 认知确认与响应式服务底层要求

首先你的部分认知存在偏差:

  • Servlet 3.1规范确实引入了非阻塞IO的支持,但不是所有Servlet默认就具备非阻塞处理能力,需要手动开启异步支持、按非阻塞模式编码才能生效
  • 不需要必须部署在Netty上,Tomcat 8+、Jetty 9+等主流Servlet容器都已经支持Servlet 3.1非阻塞特性;Netty本身不是标准Servlet容器,它是响应式框架常用的底层异步运行时
  • 要实现真正的响应式服务,必须使用非阻塞的请求处理运行时(不管是Servlet容器还是Netty这类异步运行时):响应式的核心优势是用少量线程承载高并发,要是容器层本身是阻塞模型(每请求绑定一个工作线程,请求处理完才释放线程),哪怕上层用了响应式编程框架,线程还是会被阻塞占用,完全发挥不出响应式的优势。同时要注意全链路不能有阻塞操作(比如同步JDBC调用、同步HTTP调用),否则还是会阻塞线程。

问题2 非阻塞Servlet与普通Servlet的区别及实现

核心区别

普通HttpServlet是阻塞IO模型:容器为每个请求分配一个独立的工作线程,从请求进入到响应返回的整个周期,该线程都会被占用,哪怕业务逻辑在等待IO(数据库查询、第三方接口调用),线程也无法释放处理其他请求,并发上限受线程池大小限制。
非阻塞Servlet基于Servlet 3.1的AsyncContext、ReadListener、WriteListener实现:请求进入后拿到异步上下文就可以释放容器工作线程,请求体读取、响应体写入、业务处理都通过回调方式执行,线程不会被空占,少量线程就能支撑大量并发请求。

具体实现形式

非阻塞Servlet不需要额外继承特殊类,还是可以继承HttpServlet,核心是开启异步支持+按回调模式编写读写逻辑,最简示例如下:

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@WebServlet(urlPatterns = "/non-blocking-demo", asyncSupported = true)
public class NonBlockingDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 开启异步上下文,当前容器工作线程即可释放回线程池
        AsyncContext asyncContext = request.startAsync();
        // 设置异步请求超时时间
        asyncContext.setTimeout(10000);

        ServletInputStream inputStream = request.getInputStream();
        // 注册读监听器,非阻塞读取请求数据
        inputStream.setReadListener(new ReadListener() {
            @Override
            public void onDataAvailable() throws IOException {
                // 仅当有可用数据时触发,读取过程不会阻塞
                byte[] buf = new byte[256];
                while (inputStream.isReady() && !inputStream.isFinished()) {
                    inputStream.read(buf);
                    // 自行处理读取到的请求数据
                }
            }

            @Override
            public void onAllDataRead() throws IOException {
                // 请求数据全部读取完成后执行业务逻辑
                response.setContentType("text/plain;charset=utf-8");
                ServletOutputStream outputStream = response.getOutputStream();
                // 注册写监听器,非阻塞写回响应
                outputStream.setWriteListener(new WriteListener() {
                    @Override
                    public void onWritePossible() throws IOException {
                        while (outputStream.isReady()) {
                            outputStream.write("非阻塞Servlet请求处理完成".getBytes(StandardCharsets.UTF_8));
                            // 标记请求处理完成
                            asyncContext.complete();
                            break;
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        asyncContext.complete();
                        throwable.printStackTrace();
                    }
                });
            }

            @Override
            public void onError(Throwable throwable) {
                asyncContext.complete();
                throwable.printStackTrace();
            }
        });
    }
}

常用框架实现参考

  • Spring栈:如果要基于Servlet栈做异步处理,可以使用Spring MVC提供的DeferredResult、Callable异步返回值;要做全栈响应式可以直接使用Spring WebFlux,默认运行在Netty上,也支持部署在符合Servlet 3.1规范的容器中。
  • MicroProfile栈:Quarkus的响应式能力基于Vert.x实现,可以直接使用@Route注解编写响应式接口,配合Reactive REST Client、Reactive Hibernate实现全链路非阻塞;KumuluzEE、OpenLiberty等实现也都支持MicroProfile Reactive相关规范,按官方规范编码即可。

内容的提问来源于stack exchange,提问作者Jordi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:54:04