验证SpringBoot并发处理多请求

3,080 阅读2分钟

web应用在部署时通常会部署多个实例,但是这多个实例能并发处理成百上千的请求,那么每个实例肯定都能并发处理多个请求。我们知道SpringBoot支持并发处理多个请求,如果采用默认的tomcat servlet容器,springboot可以并发处理200个请求。

接下来就通过简单的demo来验证本地启动的单实例SpringBoot应用能并发处理多个请求。

1 接口搭建

controller代码如下。

@RestController
@RequestMapping("/concurrent/request")
public class MultiConcurrentRequest {
    @RequestMapping(value = "/multi", method = RequestMethod.GET)
    public ResponseEntity<Map<String, String>> dummytsp(@RequestParam(value="msg", defaultValue="Hello") String msg) {
        System.out.println("" + new Date() + " : start : ThreadId " + Thread.currentThread().getId() + " : param : " + msg);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("" + new Date() + " : end : ThreadId " + Thread.currentThread().getId() + " : param : " + msg);
        Map<String, String> response = new HashMap<>();
        response.put("message", msg);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }
}

2 并发验证

通过PostMan或者浏览器同时发送两个请求:

http://localhost:8080/concurrent/request/multi?msg=bei

http://localhost:8080/concurrent/request/multi?msg=jing

控制台输出结果:可以看到发送的2个请求是在2个线程中并发处理的。

image-20211201001147437.png

3 怎么调试

起初打断点验证时,发现并不完全是并发处理的。断点位置如下:

image-20211201001755114.png

也是同时发送2个请求,执行结果如下。首先在15分58秒发起的2个请求,第1个请求最新遇到断点,这时第2个请求始终没进入。然后在16分05秒时按F9继续运行,可以看到第2个请求进来了,并也遇到断点暂停了;这时第1个请求虽然往下走了,但是一直到16分17秒再次按F9继续运行时,第1个请求也没有打印结束信息。16分17秒按F9继续运行后,间隔5秒后控制台输出第2个请求的结束信息。

image-20211201001842727.png

这样的结果给人感觉2个请求在一会并行一会串行处理,不符合第2节的结论。查资料发现,原来IDEA的断点支持两次suspend策略:

  • All:当任一线程遇到断点时,所有线程都被暂停。
  • Thread:当某个线程遇到断点时,只有该线程被暂停,其他线程继续执行。

image-20211201002807466.png

将上述断点的Suspend策略调整为Thread后,调试现象就和第2节的结论一致了。