java - 在等待 WebService 调用时将线程用于不同的东西

标签 java spring rest web-services tomcat

<分区>

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

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

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

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

最佳答案

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

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

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

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

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


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

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

关于java - 在等待 WebService 调用时将线程用于不同的东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52200837/

相关文章:

php - PHP获取PATCH请求数据

php - PHP 中的 REST 身份验证 (CodeIgniter)

c# - 是否可以或有必要设置ServiceStack客户端删除请求的内容类型?

java分割令人困惑的空格字符

java - 检查我的 Java 应用程序是否是从网络启动的

java - 与私有(private)方法冲突时在接口(interface)中调用默认方法

java - 如何同时运行两个代码段: one returns a String the other returns void

java - 如何停止@Bean注释的Kstream kafka消费者并继续运行spring-boot应用程序

java - Java Spring如何查询MongoDB?

java - 如何一次性为java中所有children(obj)的字段分配一个新值?