tomcat参数配置
springboot2 内嵌tomcat 自动配置文件 spring-configuration-metadata.json
tomcat执行流程
情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。 情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads但没有超过maxConnections,tomcat会把此请求放入暂存连接上,等待空闲线程。
情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads且超过maxConnections,tomcat会把此请求放入等待队列(acceptCount),等待空闲线程。
情况4:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused
情况5:tomcat没有请求过来后,在60s后,maxThreads恢复到核心线程数。
jmeter压力测试接口情况
请求接口会休眠10s
场景一
server:
tomcat:
accept-count: 2
maxConnections: 8
threads:
max: 4
min-spare: 1
tomcat运行时情况
[Running, pool size = 4, active threads = 4, queued tasks = 4, completed tasks = 0]
测试结果及分析
20次请求,10次成功,10次失败
1、同时生成20次请求
2、tomcat连接上8个请求且其中4个被最大线程数处理,等待队列(accept-count)2个,
3、后面4个20s返回成功,等待队列2个转移到暂存队列
4、最后2个30s返回成功
5、最初的10次失败,服务端可以接受最大请求数:(maxConnections+accept-count)。例如:(8+2)=10
疑点:
10次失败都是在4s左右全部失败,不清楚是那个参数控制的。网上有人测试 是在52s返回异常
经测试,4s跟jmeter设置的连接超时时间有关系,但不是这个控制
配置解释
- spring.mvc.async.request-timeout 异步请求的时间,搭配Callable使用
- connection-timeout 超时时间 是建立连接需要的时间,非连接处理的时间,
- accept-count: 20 等待队列长度
- threads.max: 20 最大线程数:用来保证系统的稳定性
- threads.min-spare: 初始线程数:保障启动的时候,如果有大量用户访问,能够很稳定的接受请求
- max-connections tomcat能够接受的最大连接数
- maxConnections和accept-count的关系为:当连接数达到最大值maxConnections后,系统会继续接收连接,但不会超过acceptCount的值。
客户端超时场景
connection timeout 报错可能出现的原因
客户端跟服务端建立连接超时,TCP三次握手失败,弱网原因。
客户端第一次请求服务端,如果一定时间内没有响应,会重试机制再次请求服务端,重试机制默认8次,时间依次是2^n-1s
例如:connection-timeout=30s 重试4次,15秒就会超时
SocketTimeoutException: Read timed out
客户端和服务端建立链接基础上,在一定时间内没有返回数据
多数是在客户端请求服务端设置的soTimeOut参数控制的
tomcat接收一个http请求
根据上面的分析我们已经可以看到tomcat的执行流程了,这里盗用网上的一张比较好的图
大致流程为
1、创建一个Acceptor线程来接收用户连接,接收到之后扔到events queue队列里面,默认情况下只有一个线程来接收
2、创建Poller线程,数量小于等于2,Poller对象是NIO的核心,在Poller中,维护了一个Selector对象;当Poller从队列中取出socket后,注册到该Selector中;然后通过遍历Selector,找出其中可读的socket,然后扔到线程池中处理相应请求,这就是典型的NIO多路复用模型。
3、扔到线程池中的SocketProcessorBase处理请求