异步 Spring 控制器与普通控制器
Async Spring Controllers vs normal Controllers
我想分析通过在 Spring 中启用异步控制器在普通控制器上启动
我可能看到的改进
这是我的测试代码。一个 API returns 一个 Callable,另一个是普通控制器 API。两个 APIs 阻塞 10secs 模拟一个长的 运行 task
@RequestMapping(value="/api/1",method=RequestMethod.GET)
public List<String> questions() throws InterruptedException{
Thread.sleep(10000);
return Arrays.asList("Question1","Question2");
}
@RequestMapping(value="/api/2",method=RequestMethod.GET)
public Callable<List<String>> questionsAsync(){
return () -> {
Thread.sleep(10000);
return Arrays.asList("Question2","Question2");
};
}
我使用此配置设置了嵌入式 tomcat,即只有一个 tomcat 处理线程:
server.tomcat.max-threads=1
logging.level.org.springframework=debug
期望 /api/1
由于只有一个 tomcat 线程,在 10 秒
后处理之前不会受理另一个请求
结果:
达到预期
期望 /api/2
由于我们立即返回一个可调用对象,因此单个 tomcat 线程应该可以自由处理另一个请求。 Callable 将在内部启动一个新线程。所以如果你点击相同的 api 它也应该被接受。
结果:
这不会发生,直到可调用函数完全执行,才会接受进一步的请求。
问题
为什么 /api/2 没有按预期运行?
@DaveSyer 是对的,/api/2 实际上表现符合预期。
我假设您正在使用网络浏览器测试行为。至少 Firefox 和 Chrome 正在阻止对同一个 URL 的多个同时请求。如果您使用 api/2 打开 2 个选项卡,第二个选项卡只会在第一个得到响应后才向应用程序发送请求。
尝试使用简单的 bash 脚本对其进行测试,例如:
curl localhost/api/2 &
curl localhost/api/2 &
curl localhost/api/2 &
它将大约同时打印 3 个响应。
只想提一下 server.tomcat.max-threads 自 Spring 引导 2.3 以来已弃用。现在在 Spring application.properties 中使用 server.tomcat.threads.max。默认值为 200。
我想分析通过在 Spring 中启用异步控制器在普通控制器上启动
我可能看到的改进这是我的测试代码。一个 API returns 一个 Callable,另一个是普通控制器 API。两个 APIs 阻塞 10secs 模拟一个长的 运行 task
@RequestMapping(value="/api/1",method=RequestMethod.GET)
public List<String> questions() throws InterruptedException{
Thread.sleep(10000);
return Arrays.asList("Question1","Question2");
}
@RequestMapping(value="/api/2",method=RequestMethod.GET)
public Callable<List<String>> questionsAsync(){
return () -> {
Thread.sleep(10000);
return Arrays.asList("Question2","Question2");
};
}
我使用此配置设置了嵌入式 tomcat,即只有一个 tomcat 处理线程:
server.tomcat.max-threads=1
logging.level.org.springframework=debug
期望 /api/1 由于只有一个 tomcat 线程,在 10 秒
后处理之前不会受理另一个请求结果: 达到预期
期望 /api/2 由于我们立即返回一个可调用对象,因此单个 tomcat 线程应该可以自由处理另一个请求。 Callable 将在内部启动一个新线程。所以如果你点击相同的 api 它也应该被接受。
结果: 这不会发生,直到可调用函数完全执行,才会接受进一步的请求。
问题 为什么 /api/2 没有按预期运行?
@DaveSyer 是对的,/api/2 实际上表现符合预期。
我假设您正在使用网络浏览器测试行为。至少 Firefox 和 Chrome 正在阻止对同一个 URL 的多个同时请求。如果您使用 api/2 打开 2 个选项卡,第二个选项卡只会在第一个得到响应后才向应用程序发送请求。
尝试使用简单的 bash 脚本对其进行测试,例如:
curl localhost/api/2 &
curl localhost/api/2 &
curl localhost/api/2 &
它将大约同时打印 3 个响应。
只想提一下 server.tomcat.max-threads 自 Spring 引导 2.3 以来已弃用。现在在 Spring application.properties 中使用 server.tomcat.threads.max。默认值为 200。