Java 异步 servlet

问题描述 投票:0回答:1

我们使用具有以下机制的异步 servlet(异步 servlet 不异步运行

@WebServlet(urlPatterns = { "/test" }, asyncSupported = true)
public class TestServ extends HttpServlet  implements AsyncServletTaskProcessor{

    /** The exec. */
    private ExecutorService exec;

    public int CALLBACK_TIMEOUT;

    public void init() throws ServletException {
        // read callback timeout form web.xml as init parameter
        CALLBACK_TIMEOUT = Integer.parseInt(getInitParameter("timeout"));
        // read thread pool size form web.xml as init parameter
        int size = Integer.parseInt(getInitParameter("threadpoolsize"));

        exec = Executors.newFixedThreadPool(size);

    }

    @Override
    public void doGet(HttpServletRequest rq, HttpServletResponse rs) {

        rs.setContentType("text/plain");
        rs.setHeader("Access-Control-Allow-Origin", "*");

        //AsyncContext asy = rq.startAsync(rq, rs);
        //asy.start(new Client(asy));

        final AsyncContext asy = rq.startAsync();

        // set the timeout
        asy.setTimeout(CALLBACK_TIMEOUT);

        // attach listener to respond to lifecycle events of this AsyncContext
        asy.addListener(new AsyncListenerImpl(asy));

        // spawn some task in a background thread
        exec.execute(new AsyncServletTaskRunner(asy, this));
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }

    @Override
    public void process(AsyncContext ctx) throws IOException, ServletException {
       //do whatever you want to do as process of each thread
    }
}

class AsyncServletTaskRunner implements Runnable {
...
}

读取器和写入器是使用 ReadListener 和 WriteListener 以及 ServletOutputStream 编写的。

线程池大小为5。

问题: 我们有 5 个不同的异步 servlet。他们每个人都有自己的执行者。每个都有不同的映射,/test1、/test2 等。但是,如果用户数量增加并且进程时间超过 10 秒,我们就会开始收到 IllegalStateExceptions 并且页面变得无响应。

我们应该为所有 servlet 使用通用的 Executor 吗?泳池的大小怎么样?我们是否应该只为应用程序使用一个异步 servlet,并在实现上进行区分?

另一个问题是我们看到异步servlet的例子没有使用任何Executor,而不是Executor的用法如下,哪种方法更好?

使用执行器:

exec.execute(new AsyncServletTaskRunner(..));

asy.start(new AsyncServletTaskRunner(..); 
java asynchronous servlets executorservice threadpoolexecutor
1个回答
0
投票

问题:我们有 5 个不同的异步 servlet。他们每个人都有自己的执行者。每个都有不同的映射,/test1、/test2 等。但是,如果用户数量增加并且进程时间超过 10 秒,我们就会开始收到 IllegalStateExceptions 并且页面变得无响应。

这听起来并不奇怪。您正在使用

FixedThreadPoolExecutor
来运行相对长时间运行的任务,因此您可以相对轻松地克服您设置的并发处理能力。

但问题来得更早。 Java EE 应用程序无法随意创建自己的线程,无论它们想要什么。如果您坚持使用执行程序服务,那么您必须使用容器管理的服务。但我不立即明白为什么你需要这样做。 Java EE 容器已经管理多个线程,并且

AsyncContext
有一个用于挂钩的内置机制。

我们应该为所有 servlet 使用通用的 Executor 吗?泳池的大小怎么样?我们是否应该只为应用程序使用一个异步 servlet,并在实现上进行区分?

您可能根本不应该设置自己的执行器服务,但如果您这样做(见上文),那么我看不出为每个 servlet 单独设置一个执行器服务会带来什么好处。

我认为尝试在单个 servlet 上加载所有异步行为没有什么特别的优势。

另一个问题是我们看到了不使用任何 Executor 的异步 Servlet 示例 [...]

是的。

AsyncContext.start()
将指定的任务分配给容器管理的线程。

哪种方法更好?

我想这取决于应用程序,但我建议

AsyncContext.start()
,直到并且除非您发现它在某种程度上不够(以及如何以及为什么)。如果您达到了这一点,那么您将拥有决定自己所需属性所需的所有信息
ManagedExecutorService

© www.soinside.com 2019 - 2024. All rights reserved.