【发布时间】:2017-06-29 19:26:35
【问题描述】:
我对 Spring Boot 比较陌生,并从他们的 getting started site 中的一个非常简单的示例开始,即(在控制器端):
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
我现在想要的是,同一控制器的多个(可能长时间运行的)请求可以并行处理。
因为我已经知道
更新:我的错:我认为这与控制器是单例有关。但确实如此:为什么它不能并行运行呢?@RestController 将被实例化为单例,所以对我来说很清楚,多个请求(由相同的方法处理)将按顺序处理 .
所以我将上面的示例更改如下,以便在每个请求上创建一个新的控制器实例,并通过某种方式检查实际发生的情况:
@RestController
@Scope(value = "request")
public class HelloController {
private static AtomicInteger count = new AtomicInteger(0);
public HelloController() {
count.incrementAndGet();
}
@PostConstruct
public void init() {
System.out.println("start request " + count);
}
@PreDestroy
public void onDestroy() {
System.out.println("end request " + count);
}
@RequestMapping("/")
public String index() throws InterruptedException {
LocalDateTime now = LocalDateTime.now();
TimeUnit.SECONDS.sleep(15);
System.out.println(now);
return "Greetings from Spring Boot! " + now + " " + count.get();
}
}
现在我希望看到请求在大约 15 秒内并行处理,但实际上我只能看到它显然是按顺序处理的,并且需要 30 秒(在标准输出上):
start request 1
2017-02-11T14:19:47.429
end request 1
start request 2
2017-02-11T14:20:02.467
end request 2
所以我的问题是:我如何才能实现并行处理此类请求,因为为每个请求创建一个实例显然是不够的?
小评论:我已经尝试将@Asnync 注释与@EnableAsync 结合使用作为应用程序类,但这似乎是“一劳永逸”,因此我无法在客户端显示响应.
stackoverflow 上的几个条目(例如 this 和 this)很有趣,但也没有回答我的问题,本教程也没有回答关于 asynchronous methods 的问题。
更新:由于一些人指出问题可能与我测试的方式有关,我尝试使用不同的浏览器运行它。有趣的是,我在 Chrome 和 Firefox 上都遇到了同样的问题。但是当每个请求都执行一个请求时,它显示了预期的行为(并行处理请求)——所以我被浏览器愚弄了......
【问题讨论】:
-
如何执行并行请求?
-
你如何测试调用你的 HelloController 端点?通过使用浏览器(打开 2 个选项卡)或单元测试(使用线程)?
-
“因为我已经了解到@RestController 将被实例化为单例,所以我很清楚,多个请求(由相同的方法处理)将按顺序处理。”这种说法是错误的。在 servlet 容器中,每个请求都在不同的线程中处理。除非您的控制器方法是同步的,否则请求将由您的控制器并行处理
-
此外,由于您的控制器是单例,
@PostConstruct和@PreDestroy在容器生命周期内只应调用一次 -
@gregfqt:他修改Controller使用scope="request"
标签: java spring-boot parallel-processing