如何处理WebSphere中多个AJAX请求导致的高线程使用率



在压力测试期间,我被告知需要减少应用程序的线程使用量。

我们所有的其他应用程序都遵循每页1个请求的模式,而我创建了一个单页应用程序,它在加载时触发8个AJAX请求。

我在Websphere 8.5.5.1(Servlet 3.0)上运行。

我从浏览器一个接一个地向同一个Servlet发出8个AJAX请求,所以它们是并行的。

Servlet基本上检查请求参数,并通过http调用相应的ESB服务,然后返回响应。

如果我在这里说的任何话都是垃圾,请纠正我,因为我没有100%相信…

我的理解是,当请求到达Websphere时,它会从线程池中获得一个线程,并使用该线程来执行Servlet,并保持同一线程,直到返回响应。我还认为线程在等待ESB的响应时会阻塞。是这样吗?

我正在考虑以下3个选项:

1) 在Servlet 3.0中,我们可以对异步Servlet做的最好的事情是将请求放在队列中,并将线程返回到池中。然后,一个或多个线程将通过为请求提供服务的队列。因此,我们只是将一个线程池交换为另一个,但我们可以限制/控制第二个线程池的大小。

如果我们有Servlet 3.1(JSR340),我们可以使用ReadListener,我猜我们可以在等待ESB响应时避免线程阻塞?

2) 在前端对AJAX请求进行排队,这样我就不会触发8个AJAX请求,而是触发3个,当它们完成时再触发下一个,以此类推,这样并行的请求就永远不会超过3个。

3) 向Servlet发出1个AJAX请求,让它调用所有8个ESB服务并组合结果。

你能告诉我以上任何解决方案是否有效,我是否完全理解它们,并提出其他可能的解决方案吗?

谢谢。

尝试逐点回答:

  1. "Websphere从线程池中获取一个线程,并使用该线程执行Servlet,并保留同一线程,直到返回响应。"您的理解是错误的。如果WS使用旧的IO,这是正确的,但WS 6.1版以后使用本机IO(NIO)和异步IO(AIO),这允许少数线程满足数千个并发连接。请参阅本参考资料。因此,您不应该担心从AJAX客户端进行并发连接,并且并行性很好
  2. 话虽如此,应用程序必须尝试并避免执行任何阻塞操作,这些操作会阻塞任何能够处理多个并发连接的工作线程。只要想想如何异步执行每个任务,这意味着你应该能够在不阻塞自己的情况下完成任务。在您的情况下,您正在等待(并阻止)来自ESB的响应。将有大约8个到ESB服务的阻塞连接。请查看您是如何调用ESB的,以及是否可以使用NIO进行这些调用。理解WS是调用ESB的客户端,它必须使用非阻塞IO来执行在ESB上执行的操作
  3. 或者:有没有一种方法,ESB也可以异步运行,并释放WS请求线程?ESB可以在处理完请求后回调WS服务URL,然后可以创建AJAX响应。这样就不会占用WS线程

在你上面的选项中,显然#1和#3对你没有帮助#2当然会将ESB的并行操作限制为三个。但是,我建议查看对ESB的调用是否可以以异步方式和非阻塞方式进行。那将是理想的。

更新

要从应用服务器对外部服务进行异步和非阻塞调用,请考虑使用类似库的异步http客户端。默认情况下,它使用Netty,但也可以插入其他NIO框架。这个项目的README.md提供了一些很好的例子,说明如何进行HTTP调用,并在完成HTTP请求时编写响应。您可以使用onCompletion将响应写回您的客户端。

结论性发言

  1. 在监听客户端时,要做一个无阻塞的服务器。尽可能确保容器/服务器的请求线程不会阻塞
  2. 在调用外部服务时,要成为一个非阻塞客户端。这将允许您使用少数线程进行大量请求

最新更新