一、背景
因为看到一道面试题,问SpringBoot默认可以接受的最大并发量是多少,这个问题其实考的是web服务器的配置,因为SpringBoot默认的web服务器是tomcat,于是去了解了一下tomcat的相关配置
二、tomcat的相关配置以及默认值
/**
* Maximum number of connections that the server accepts and processes at any
* given time. Once the limit has been reached, the operating system may still
* accept connections based on the "acceptCount" property.
*/
private int maxConnections = 10000;
/**
* Maximum queue length for incoming connection requests when all possible request
* processing threads are in use.
*/
private int acceptCount = 100;
/**
* Maximum amount of worker threads.
*/
private int maxThreads = 200;
/**
* Minimum amount of worker threads.
*/
private int minSpareThreads = 10;
- maxConnections:服务器在任何给定时间接受和处理的最大连接数。一旦达到限制,操作系统仍然可以接受基于“acceptCount”属性的连接。
- acceptCount:当所有可能的请求处理线程都在使用时,传入连接请求的最大队列长度。
- maxThreads:最大工作线程数。
- minSpareThreads:最小工作线程数。
这里需要留意的是maxConnections的描述,可以理解为服务器达到最大连接数之后,仍然可以通过acceptCount来接收请求,所以SpringBoot可以接受的最大并发量应该是maxConnections+acceptCount,也就是10100。这是按照tomcat能接受的最大任务量来算的,可以接受这么多连接,但并不是同时在处理的任务数量,同时处理的任务数量看的是tomcat的最大工作线程数。
三、动手做实验
下面我手动改了下tomcat的这几个配置,然后写了一个测试接口,用JMeter测试了一下
首先把yaml中的默认配置改下
server:
port: 8002
tomcat:
#最大连接数
max-connections: 20
#最大队列长度
accept-count: 3
#最小工作线程数
min-spare-threads: 5
#最大工作线程数
max-threads: 10
写一个测试接口
@GetMapping("/test")
public String test() {
log.info("线程:{}", Thread.currentThread().getName());
return "success";
}
配置下JMeter,用20个并发
执行完,全部成功,控制台打印如下
可以看到,因为执行很快,所以只用到了最小的工作线程数5个
下面我们让线程阻塞,睡个3s
@GetMapping("/test")
public String test() throws Exception {
log.info("线程:{}", Thread.currentThread().getName());
Thread.sleep(3000);
return "success";
}
再跑下JMeter,可以看到控制台打印如下
这时候达到了最大的工作线程数10个
下面加到并发数量,看看效果,把并发数量调到30
跑一下,可以得到如下结果
有7次请求是失败的,报错是Connection refused: connect 连接被拒绝
看下控制台
有23条日志记录
为什么是23条请求被成功处理了呢,原因是最大连接数的20,加上最大队列长度的3,大概的处理步骤如下
- 30条请求在同一时间发起,有7条直接被拒绝,23条接收
- 因为最大工作线程是10,所以先处理了10条请求
- 10条处理完成之后,继续处理后面10条
- 最后处理剩下的3条
四、举个例子
用下面的参数,我们用去饭馆吃饭举个例子
#最大连接数
max-connections: 20
#最大队列长度
accept-count: 3
#最小工作线程数
min-spare-threads: 5
#最大工作线程数
max-threads: 10
有30个请求,就好比有30个人想到这家饭馆吃饭,但是饭馆最多只能容纳20个人(max-connections),饭馆外面能还可以有3个人(accept-count)排队等待,剩下的7个人就直接走了,而这个饭店平时有5个厨师(min-spare-threads)炒菜,当这些厨师忙不过来的时候,就会增加到10个厨师(max-threads)来炒菜。