关于springboot内置tomcat最大请求数配置的一些问题

前言

springboot内置了tomcat。那么一个springboot web应用,最大的请求链接数是多少呢?很早以前就知道这个是有个配置,需要的时候,百度一下即可。但,事实并非如此,有几个问题我想大多数人还真不知道。比如:

  • 为什么会有最大连接数和等待队列两个配置:要限制最大链接,用一个最大连接数限制即可,搞个等待队列有什么用呢?(我看网上有说,就像是餐厅有在餐厅里等待上菜的(最大链接数),也有在外坐小板凳排队的(等待队列),但,餐厅这么设计,可以说是由于实际场地等因素,那程序呢?它考虑的是什么?)
  • 有两个应用A、B,A调用B的一个接口,A在http请求方法的开始和结尾记录了时间,相减得到值是20s,B方法在controller方法的开头和结尾(或者AOP拦截)也记录了时间是10s,如果认为接口15s以内都是正常的,那么B就会认为自己的接口正常,A认为B的接口不正常。那么这差的10s问题出在哪里?

说明:

  1. 有些结论叙述不太准,但是这并不重要,理解所表达的意思即可,不要纠结一个答案;
  2. 有些配置的默认值,或者结论现象和网上其他说法不同,不必怀疑,可能大家都是对的,我们的环境不同罢了

正文

关于spirngboot内置tomcat的最大请求数,大体有如下四个配置:(后续配置中,如不特殊说明,都是按照这个参数值来进行验证)

#最少的工作线程数,默认大小是10
server.tomcat.threads.min-spare=1
#最多的工作线程数,默认大小是200
server.tomcat.threads.max=2
#最大连接数,默认大小是8192。表示Tomcat可以处理的最大请求数量,超过8192的请求就会被放入到等待队列。
server.tomcat.max-connections=2
#等待队列的长度,默认大小是100。
server.tomcat.accept-count=4

结论

先直接上结论,后续一一用代码来实际论证:

  1. 最小工作线程数server.tomcat.threads.min-spare是一个优化配置,应用启动就会创建相应数目的线程(不管有没有请求),这些线程是不会被销毁的,而server.tomcat.threads.max是在请求的任务数多的时候,会临时创建的线程,之后这些线程会被销毁;
  2. 最大可接受的请求数为:server.tomcat.max-connections + server.tomcat.accept-count,超过该数目会拒绝请求;
  3. 最多能同时工作的线程数是:server.tomcat.threads.max
  4. 如果配置server.tomcat.max-connections 小于server.tomcat.threads.max,那么实际中创建的任务线程数应该是:server.tomcat.max-connections
  5. 最大连接数中的请求没有处理完之前,是不会处理等待队列中的请求的;
  6. 假如把最大连接数和等待队列都看作容器:那么
    • 并非是要等最大链接数中的链接,全部处理完了,才会处理等待队列中的链接,而是最大链接容器中,有空位了,等待队列中就会有个链接进入最大链接容器,从而又可以接受一个新的链接了(debug源码发现:其实接受最大链接的池子是一个无限队列,但是通过server.tomcat.max-connections来控制这个最多能容纳的链接,当等于max-connections之后,新的链接就会进入等待队列,判断是否拒绝链接,是判断当前请求中,server.tomcat.accept-count的值是否大于等于配置值,如果是就拒绝链接)
    • 等待队列的存在是有意义的,特别是在异步请求

论证

这里我准备了一个接口,不考虑其他代码(如拦截器、过滤器之类的)的执行耗时,就认为这个接口的耗时时间为10s:

@GetMapping("/test10")
public String test10() throws InterruptedException {
    log.info("当前线程test10:{}.", Thread.currentThread().getName());
    Thread.sleep(10000);
    return "test10s";
}

应用启动就会创建min-spare个线程

依次将server.tomcat.threads.min-spare设置为1、2、3,会发现项目启动后,就会创建对应多个数目的线程数(不要将该数值设置的大于server.tomcat.threads.max),当链接超过了这个最小的线程数之后,就会再创建线程,但是不会超过最大链接数,这些线程最终会被销毁(项目启动时创建的server.tomcat.threads.min-spare的线程却不会被销毁)

image.png

image.png

image.png

最大可接受请求数:server.tomcat.max-connections + server.tomcat.accept-count

现在配置的server.tomcat.max-connections + server.tomcat.accept-count 为7,那么发起7个请求,就应该有6个请求得到正常响应,一个请求被拒绝:

image.png

最多能同时工作的线程数是:server.tomcat.threads.max

同样,用上面的验证结果,看响应时间:

image.png

我配置的server.tomcat.threads.max为2,意味着同时有两个线程会执行请求。那么,接口耗时10s,每两个线程的响应时间是相同的,两两之间相差10秒。

想一下开头说的:A、B两应用接口调用有10s的时间对不上,也许有一种可能就是这里:从接口打印的时间来看,是10秒,但是实际的响应却是10s、20s、30s。

由此可见:有些项目所谓的接口响应时间的记录,其实仅仅是记录的业务代码的执行时间。对于请求方而言,并非接口的响应时间。知道这个,对于分析问题,又多了一种思路了。

如果配置server.tomcat.max-connections 小于server.tomcat.threads.max,那么实际中创建的任务线程数应该是:server.tomcat.max-connections

这种配置法,在实际中是不存在的,我想,应该不会有人这么干吧!!!

server.tomcat.threads.min-spare=1
server.tomcat.threads.max=3
server.tomcat.max-connections=2
server.tomcat.accept-count=4

依然是7个请求并发,结果一个失败,6个成功,耗时30秒:

image.png

看这个图,时间依旧是两两一组,说明虽然允许最多创建3个任务线程,但是实际最大链接有2个,那么也认为只有两个任务要执行,而不会管等待队列中的任务。只有等最大链接池中的任务有执行完的了,才会让等待队列中的任务进来。
如果把server.tomcat.threads.min-spare设置为3,结果也是一样的。

最大连接数中的请求没有处理完之前,是不会处理等待队列中的请求的

这个结论是在其他地方看到的,当时一直不理解:假如最大链接数中有10个请求,等待有2个,那么必须要等到这10个请求全部完成了,才会处理等待队列的两个吗?其实,这句话的意思应该是,创建出的线程只会处理最大连接数中的请求,当有一个请求完了之后,才会让等待队列中的请求进来,然后然后又被任务线程处理。即便有空余的任务线程,也不会处理等待队列中的请求。在:

如果配置server.tomcat.max-connections 小于server.tomcat.threads.max,那么实际中创建的任务线程数应该是:server.tomcat.max-connections

已经论证了。

等待队列存在的作用

虽然之前也有说了,最大连接数中的请求没有处理完之前,是不会处理等待队列中的请求的,但这个作用意义不大,毕竟在实际中,不会有人配置工作线程数小于最大线程数。
所以,从以上现象中看,这个等待队列的意义不大(从我的测试结果看,这个确实没有啥意义,但是如果看源码,它还是有作用的,但我认为按照官方指导数来配置就可以了,理解它的作用比较抽象),除非————使用异步请求

之前的接口,都是同步请求的:工作线程从最大链接容器中拿取一个人请求处理,处理完之后,再拿取下一个,它所针对的是最大链接,和等待队列没有关系,但等待队列看到最大链接中有空位了,就安排它的一个链接请求去补位,所以,从这里看它的存在意义不大。

但如果是异步请求中,这个等待队列就有意义了:如之前所说,工作线程只管最大请求链接中的请求。那么如果我允许项目的最大链接说是10,只有一个参数控制这个值的话,在异步线程中几乎可以认为会同时处理10个请求,但有了等待队列,则可以控制同时处理的请求数了。描述的不是很准确,直接看结果:增加一个异步请求接口和之前的同步请求逻辑一样,从客户端的角度看,这两个接口都是耗时10s:

@GetMapping("/testCallAble")
public Callable<String> testCallAble(){
    return () -> {
        log.info("当前线程:{}.", Thread.currentThread().getName());
        Thread.sleep(10000);
        return "hello";
    };
}

使用如下配置参数,依次请求两个接口:7个并发请求:

server.tomcat.threads.min-spare=1
server.tomcat.threads.max=2
server.tomcat.max-connections=4
server.tomcat.accept-count=2

异步请求结果:1个请求失败,总耗时20秒:有4个请求(server.tomcat.max-connections的值)是同一时间返回的:说明任务线程由于异步请求,它空闲出来之后会处理最大链接数中的其他请求,但是不会处理等待队列中的请求。如果没有等待队列,那么就会造成这个异步线程会一下处理6(server.tomcat.max-connections+server.tomcat.accept-count)个请求链接的业务方法,这个时候可能服务器没有足够的资源。
image.png

同步请求结果:1个请求失败,总耗时30秒:每两个请求的响应时间是相同的:
image.png

通过以上例子以及之前的例子,对于这个等待队列,应该有了个较为清晰且模糊的认识了吧。哈哈!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/578969.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

强化学习-MAPPO算法解析与实践-Multi Agent Proximal Policy Optimization

一 算法简介 mappo 是一种将ppo算法扩展到多智能体情况的算法&#xff0c;在讨论过这种算法的论文中&#xff0c;比较有名和权威的是Nips2021上发表的《The Surprising Effectiveness of PPO in Cooperative》。比较遗憾的是&#xff0c;可能作者出于自己不是最早提出mappo算法…

Avalonia UI跨平台WPF

Avalonia是一个强大的框架&#xff0c;使开发人员能够使用.NET创建跨平台应用程序。 它使用自己的渲染引擎绘制UI控件&#xff0c;确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。 官网链接&#xff1a; 官网链接 文档链接&#…

mstsc 远程桌面由于以下原因之一无法连接到远程计算机

问题 想使用win自带的局域网远程工具mstsc远程连接电脑。如何连接&#xff1a;只需要两台电脑在同一个局域网内&#xff0c;然后使用被远程电脑的ip地址、Microsoft用户名和密码。 但是连接的时候会跳出来如下提示&#xff1a; 远程桌面由于以下原因之一无法连接到远程计算机…

【每日刷题】Day23

【每日刷题】Day23 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 2. 链表的回文结构_牛客题霸_牛客网 …

C++11新特性:lambda表达式

目录 1.lambda表达式 1.1 C98中的一个例子 1.2 lambda表达式 1.3 lamzbda表达式语法 1. lambda表达式各部分说明 2. 捕获列表说明 1.4 函数对象与lambda表达式 1.lambda表达式 1.1 C98中的一个例子 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0…

spring的常用注解

目录 1.前言 2.web url映射 2.1RequestMapping 2.2PostMapping 2.3GetMapping 3.参数接受和接口响应 3.1RequestParam 3.2RequstBoby 3.3ResponseBoby 3.4RestController 4.bean的存储 4.1Controller 4.2Service 4.3Repository 4.4Compontent 4.5Configuration …

判断n以内的素数个数的五种方法+时间对比

目录 方法一&#xff1a;暴力法 复杂度 方法二&#xff1a;跨度为6的倍数的优化 复杂度 方法三&#xff1a;埃氏筛法 复杂度 方法四&#xff1a;埃氏筛法的改良 复杂度 方法五&#xff1a;线性筛 复杂度 性能对比测试 练习 方法一&#xff1a;暴力法 就是写一个函…

Nacos 集群 On K8s 实践服务注册发现、服务动态配置

一、K8s 部署 Nacos 集群 安装规划 组件replicas类型mysql1StatefulSetnacos3StatefulSet 使用 k8s 版本为&#xff1a;v1.18.0 。 本次使用 OpenEBS 来作为存储引擎&#xff0c;OpenEBS 是一个开源的、可扩展的存储平台&#xff0c;它提供了一种简单的方式来创建和管理持久…

JavaEE——Spring Boot入门

目录 &#x1f4da; JavaEE——Spring Boot入门 &#x1f527; 1. 新建Spring Boot项目 &#x1f6e0; 2. 添加pom依赖 &#x1f4dd; 3. 添加application.yml文件 &#x1f4c2; 4. 创建Dao层 &#x1f527; 5. 创建Service层 &#x1f5a5;️ 6. 创建Controller层及HT…

easyExcel快速入门

目录 &#x1f9c2;1.简单介绍 &#x1f32d;2.快速入门 &#x1f953;1.导入依赖 &#x1f37f;2.导出到excel &#x1f38f;3.读入数据 &#x1f389;4.下载 1.简单介绍 传统操作Excel大多都是利用Apach POl进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多…

redisson分布式锁的单机版应用

package com.redis;/*** author linn* date 2024年04月23日 15:31*/ import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.…

多端文件互传软件-LocalSend

一、前言 日常学习或者是工作需求&#xff0c;需要手机和电脑互传文件。用到频率低的话&#xff0c;使用即时通讯软件也就够了。 像我日常使用的多端互传文件软件是LocalSend。 二、 LocalSend LocalSend是一款基于局域网的文件传输工具。 LocalSend是一种用于在本地网络中…

super与this

目录 原型链与继承继承中的原型链 classsuper与this 我们可能会对一个问题感到好奇&#xff1a;为什么在派生类中&#xff0c;我们需要在调用this之前调用super。我们通常将其视为一种规范&#xff0c;却很少深入探究这个规范的真正意义。许多人认为super不过是ES6之前继承方式…

SpringBoot 3.2.5 引入Swagger(OpenApi)

SpringBoot 3.2.5 引入Swagger&#xff08;OpenApi&#xff09; pom文件配置文件启动类Controller 层ApiFox题外话 springdoc-openapi 和 swagger 都可以用&#xff0c;用其中一个就行&#xff0c;不用两个都引入。 这里简单记录以下springdoc-openapi。 springdoc-openapi(J…

每日算法之两两交换链表中的节点

题目描述 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&…

sheng的学习笔记-AI-支持向量机(SVM)

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 目录 什么是向量机 SVM算法原理 SVM基本模型 SVM对偶问题 什么是对偶问题&#xff1a; 为什么使用对偶问题 拉格朗日定理 拉格朗日乘子法 对偶问题算法 非线性SVM算法原理 核函数 常用核函数 软间隔与正则化 软…

RabbitMQ-死信队列

面试题&#xff1a;你们是如何保证消息不丢失的&#xff1f; 1、什么是死信 在 RabbitMQ 中充当主角的就是消息&#xff0c;在不同场景下&#xff0c;消息会有不同地表现。 死信就是消息在特定场景下的一种表现形式&#xff0c;这些场景包括&#xff1a; 1. 消息被拒绝访问&…

教你一分钟快速部署 Llama3 中文大模型

之前百度创始人李彦宏先生曾经说过“开源大模型会越来越落后&#xff0c;闭源模型会持续领先”&#xff0c;但国货表示真的不服&#xff0c;紧接着被扎克伯格同学就给了当头一棒&#xff0c;向他展示了什么叫做顶级开源大模型。那变听我娓娓道来。 美国当地时间4月18日&#x…

使用NGINX做局域网内 浏览器直接访问链接 拓展外网链接访问本地

达成目的功能&#xff1a; 在本地服务的一个文件路径下&#xff0c;局域网内用ip和路径名访问到对应的地址&#xff1b;如 10.5.9.0/v1 即可访问到 某个固定本地地址目录 V1下&#xff0c;名为index.html的文件。前言 NGINX 是一个非常流行的开源 Web 服务器和反向代理服务器…

5分钟梳理银行测试,文末附带实战项目,0经验入行so easy

很多银行招聘都要求有相关从业经验&#xff0c;这对于想跨入这个岗位的0经验从业同学可真犯了难 “你都不让我上岗&#xff0c;我哪来的工作经验呢&#xff1f;” 为了解决这个问题&#xff0c;小编整理了本篇文章&#xff0c;从3个方面介绍银行项目是如何进行测试的 银行的…
最新文章