使用多个线程处理单个 HTTP 请求

Serving single HTTP request with multiple threads

Angular 4 应用程序将记录列表发送到已部署在 Websphere 8 Servlet 容器中的 Java spring MVC 应用程序。然后将该列表插入到临时 table。批量插入后,进行过程调用以进行一些计算和 return 结果。根据插入到 temp table 中的列表的大小,它可能需要介于 3000 毫秒(N ~ 500)、6000 毫秒(N ~ 1000)、50,000+ 毫秒(N > 2000)之间的任何时间。

我的任务是创建数据块并同时将它们发送到数据库进行处理。在线程(期货)return 结果之后,我会将它们汇总并 return 返回给客户端。总而言之,我会将同步调用拆分为多个异步进程(同时执行),然后 return 通过启动 HTTP 调用的同一线程返回客户端 - 进入我的控制器。

一切都会好起来的,如果我的一位更有经验的同事不强烈反对这种方法,我就不会问这个问题。他的理由是,使用这种方法很容易因线程中断/超时/信号量等原因而出现异常。您好甚至说应该在 Web 容器中避免多线程,因为它可能会在 Servlet 容器用完线程时崩溃。 他建议我们应该让浏览器以块的形式发送多个 AJAX 请求和 aggregates/present 数据。

你能帮我了解哪种方法更好吗?为什么?

我会说你的方法要好得多。

  1. 应用程序逻辑创建的线程不是应用程序容器线程,仅受操作系统限制。虽然每个 AJAX 请求都使用来自应用程序容器的线程。因此,第二种方法会降低吞吐量并增加达到应用程序容器限制的可能性,而第一种则不会。还应考虑性能,因为创建线程比通过网络发送请求要便宜得多。另外每个网络请求都使用额外的资源 authentication/authorization/encryption 等等

  2. 编写正确的多线程代码肯定更难,而且很容易出错。但是,它不应该阻止您这样做,因为并发可以显着提高您的性能。使用 Future 处理中断和超时非常简单,您肯定不需要这里的信号量。

  3. 向客户端公开此逻辑看起来像是破坏了封装。想象一下,您使用 rest api 强制您通过将数据分成块来发送多个请求。我应该使用什么块大小?如何处理timeouts/interrupts?我应该发送多少个请求?等。您将在这两种方法中遇到几乎相同的挑战,但使用专门为此库(如 ExecutorService 和 Future)设计的库来处理它们要容易得多。