【问题标题】:Using thread for something different when waiting for WebService call [closed]在等待 WebService 调用时使用线程来做不同的事情[关闭]
【发布时间】:2026-01-05 17:00:01
【问题描述】:

我有一个非常简单的 Spring 应用程序,它发布了一个 REST 服务 (1)。该服务正在调用另一个 Web 服务 (2) 来检索数据。检索数据的调用需要 2-3 秒。

我现在遇到的问题是会有很多人调用 Spring Web 服务(1),但是响应时间急剧增加,因为每个调用都必须等待第二个调用完成。

我目前的理解是,每个未直接处理的呼叫都会进入队列。我有四个 CPU,每个 CPU 有 2 个线程,8 个同时工作的线程。

当线程等待服务调用(2)完成时,有什么方法可以释放线程?

【问题讨论】:

  • 你在标记这个“tomcat”:这是运行在tomcat上的spring应用,还是其他地方的spring应用,在tomcat上调用webservices?

标签: java spring rest web-services tomcat


【解决方案1】:

处理这个问题的正常方法是拥有比 CPU 更多的线程,并依靠线程调度程序在线程之间切换。

例如...假设有 2 个内核和 3 个或更多线程

  1. 服务器接受请求 R1 并开始在内核 C1 上运行的线程 T1 上处理它。
  2. 服务器接受请求 R2 并开始在核心 C2 上运行的线程 T2 上处理它。
  3. 服务器接受请求 R3 并将其分派给线程 T3。 T3 目前无法运行(没有可用内核),因此它等待被调度。
  4. T1 到达将请求发送到其他服务的位置。请求被发送,T1 阻塞等待回复。这释放了核心 C1。
  5. T3 计划在 C1 上运行,并且正在处理请求 R3。

基本上,阻塞、解除阻塞和调度都是由 Java 和操作系统在后台处理的。如果您使用的是 Servlet,容器将处理工作线程池以及将请求分派给线程。

这适用于多达一百个左右的1 个线程;即同时处理一百个左右的请求。除此之外,过多线程(例如线程堆栈内存)和过多调度/上下文切换的开销会影响吞吐量。此时,您需要研究一个支持异步处理的框架2,其中线程在请求​​之间切换而不是阻塞。


1 - 线程过多会影响性能的点将取决于各种难以预测的因素。

2 - Servlet 3.0 规范支持异步请求处理,因此如果您需要,请寻找支持 Servlet 3.0 的 Web 容器;例如Tomcat 7 或更高版本。

【讨论】:

  • 感谢您的精彩解释。这也适用于从外部库调用方法而不是调用 Web 服务时,例如网络服务模板?
  • 也许吧。这取决于外部库的作用。如果只是在不进行任何 I/O 且不与其他线程同步的情况下进行计算,则 T1(在示例中)可能永远不会阻塞。在这种情况下,T3 通常必须等到 T1 完成才能安排。
最近更新 更多