阿里二面:SpringBoot同时可以处理多少个请求?直接懵了。。。

SpringBoot以其简洁高效的开发方式和强大的内嵌容器特性,为开发者提供了构建高性能后端服务的便利。然而,当面临高并发场景时,理解并合理配置Spring Boot应用以达到最佳的并发处理能力至关重要。在Spring Boot中,应用程序对HTTP请求的并发处理主要依赖于内嵌的Servlet容器(如Tomcat)。接下来我们以Tomcat为例谈谈这个问题。

本文以SpringBoot2.7.0为例。

在接下来讲解Tomcat工作线程池之前,你可以先了解一下Java线程池的工作原理,请参考这篇文章:Java线程池最全详解

请求处理

我们的程序实际上是运行在Tomcat里的。所以SpringBoot可以处理多少请求,其实也就是看Tomcat可以处理多少请求。Tomcat的工作线程池负责接收并处理这些请求。在SpringBoot中关于Tomcat工作项城池的参数可以在spring-boot-autoconfigure的依赖包中的spring-configuration-metadata.json中有如下四个参数控制Tomcat的工作线程池:

{
	{  
	  "name": "server.tomcat.threads.max",  
	  "type": "java.lang.Integer",  
	  "description": "Maximum amount of worker threads.",  
	  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Tomcat$Threads",  
	  "defaultValue": 200  
	},  
	{  
	  "name": "server.tomcat.threads.min-spare",  
	  "type": "java.lang.Integer",  
	  "description": "Minimum amount of worker threads.",  
	  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Tomcat$Threads",  
	  "defaultValue": 10  
	},
	{  
	  "name": "server.tomcat.max-connections",  
	  "type": "java.lang.Integer",  
	  "description": "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.",  
	  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Tomcat",  
	  "defaultValue": 8192  
	},
	{  
	  "name": "server.tomcat.accept-count",  
	  "type": "java.lang.Integer",  
	  "description": "Maximum queue length for incoming connection requests when all possible request processing threads are in use.",  
	  "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Tomcat",  
	  "defaultValue": 100  
	}
}

我们来看一下这四个参数的含义:

  • server.tomcat.threads.max:用于配置Tomcat内嵌服务器的工作线程池的最大工作线程数。工作线程用于处理接收到的HTTP请求,处理完毕后将返回到线程池中等待下一个请求。当并发请求数量小于等于 threads.max 时,Tomcat尽可能使用现有的工作线程来处理请求,如果并发请求数量超过了 threads.maxTomcat不再创建新的工作线程,而是将请求放入队列等待。该值可以看做是一个临时工,如果并发请求的数量在threads.min-sparethreads.max之间,就会使用这些临时工线程进行处理。默认值为200。主要关注的是工作线程池,用于处理请求的线程数。适用于调整并发请求的处理能力。

  • server.tomcat.threads.min-spare:确定了工作线程池的最小空闲线程数量,即使没有请求需要处理,也会保持这些线程处于等待状态,以便快速响应新的请求。该值可以看做是一个长期工,如果并发请求数小于min-spare,就会使用这些线程去处理请求。默认值是10,即使没有活跃的请求,Tomcat也会保持至少 10 个空闲线程。

  • server.tomcat.max-connections:用于配置Tomcat内嵌服务器的连接池的最大连接数。即允许同时存在的最大连接数。这个连接数是针对整个连接池的,不仅仅是工作线程的数量。当并发请求数量导致服务器需要创建新的连接时,Tomcat 会检查连接池中的连接数是否已经达到了 max-connections 配置的最大值。如果已经达到最大值,新的连接请求将被放入等待队列中,直到有连接被释放。默认值8192。

  • server.tomcat.accept-count:用于配置Tomcat连接器所允许的最大等待接受连接的请求数(即等待队列)。当所有线程都在处理其他请求时,新的连接请求将会排队等待。如果队列已满,额外的连接将被拒绝。默认值是100。

我们以饭馆的示例去说明这几个参数之间的关系:
我们把Tomcat比作一家热门的餐厅,每个顾客都是一个请求。餐厅里一直有一部分厨师一直待命,无论有没有顾客,确保随时能够处理点单。这部分厨师就是min-spare(长期工),当餐厅遇到一些大的宴会时,餐厅老板就会从外面找过来一批厨师帮忙,这部分厨师就是临时工,临时工+长期工就是(max)。餐厅的座位就表示同时最大可以容纳啊就餐的顾客人数,即max-connections。假如某时餐厅生意火爆,餐厅的座位都坐满以后,此时餐厅就会想办法在餐厅门口放上一排座椅,可以让后来的顾客在这里等待,假如里面有顾客吃完,这时外面等待的顾客就可以进去用餐。如果餐厅门口的座椅也做满,再来的顾客就会离开。

假如上述就是那家餐厅,2个绿色框代表长期工厨师即min-spare,3个红色框代表临时工厨师,共有5名厨师,即max数量,5个棕色的队列即餐厅椅子数量,即5个max-connections,餐厅最多可以容忍5名顾客吃饭,2个橘色队列代表门口等待区椅子数量,即2个accept-count。假如此时来了4个客人,那就可以区餐厅吃饭,如果来了7个客人,那么有5个客人进去吃饭,2个客人在门口等待,如果来了8个客人,那么有5个客人进去吃饭,2个客人在门口等待,剩下1个客人就会直接离开。

示例

我们创建一个SpringBoot项目,我们将上述四个参数分别修改为如下:

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

然后我们在定义一个接口,用于模拟客户端请求:

@RestController  
@RequestMapping("test")  
public class TestMaxRequestController {  
  
    @GetMapping("maxRequest")  
    @ResponseBody  
    public String testMaxRequest() throws InterruptedException {  
        System.out.println("当前请求线程: "+Thread.currentThread().getName());  
        Thread.sleep(2000);  
        return "Hello World";  
    }  
}

我们启动项目,使用JVisualVM监测一下此时项目中的线程数为2个:

image.png

此时我们使用Apifox发起一个请求,观察线程数没有增长。我们在使用Apifox中模拟3个线程同时请求,发现此时线程数变成5个:
image.png

我们继续增加线程数到7个,我们发现线程数还是5个,因最大线程数等于5个:

image.png

后台请求全部成功:
image.png

我们继续增加线程数到8个,此时线城数依然是5个,设置请求超时时间为1秒,但是有一个请求失败:

image.png

image.png
image.png

服务端只处理了7个请求:
image.png

结论

SpringBoot可以同时处理多少个请求,需要看其内嵌的Sevlet处理线程的能力,以Tomcat为例,即Tomcat可以处理多少请求,这需要看配置文件中设置的server.tomcat.accept-count以及server.tomcat.max-connections的大小。Tomcat同时可以处理的请求为server.tomcat.accept-count加上 server.tomcat.max-connections。实际生产应用中我们需要根据服务器,硬件的配置等综合因素考虑后,调节这两个值,确保应用程序能够处理预期的并发量。

本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等。

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

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

相关文章

Docker最新超详细版教程通俗易懂(基础版)

Docker概述 概念:容器虚拟化技术,系统平滑移植,解决了运⾏环境和配置问题的软件容 器,⽅便做持续集成并有助于整体发布的容器虚拟化技术 意义:Docker的出现使得Docker得以打破过去程序即应⽤的观念,透过…

Flink中的时间语义和TTL

时间语义 事件时间(Event Time) 事件时间是数据生成的时间,是数据流中每个元素或者每个事件自带的时间属性,一般是事件发生的时间,在实际项目中作为前端的一个属性嵌入。在理想情况下,数据应当按照事件时…

TeX:一款功能强大的Telegram安全监控与管理工具

关于TeX TeX是一款功能强大的Telegram安全监控与管理工具,该工具专为Telegram设计,可以实现针对Telegram的安全监控与管理。 TeX旨在帮助安全研究人员、调查人员和执法人员收集和处理针对网络犯罪分子的取证信息,其中包括网络犯罪、欺诈攻击…

vue3-深入组件-透传属性

透传属性 (透传 attribute) 什么是透传属性(透传 attribute)? 传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者是事件监听器,例如 class style id 等。 属性继承 当一个组件以单…

STM32 1-5

目录 STM32简介 点亮PC13LED GPIO LED闪烁 LED流水灯 按键控制LED 光敏传感器控制蜂鸣器 OLED调试工具 OLED显示 EXTI外部中断 对射式红外传感器计次 旋转编码器计次 继续 STM32简介 点亮PC13LED main.c #include "stm32f10x.h" // D…

【linux】复制cp和硬连接、软连接的区别? innode 关系?

1.命令: cp -r [源文件或目录] [目的目录] #复制 ln -s [被链接的文件] [链接的目录/名称] #软连接 ln [被链接的文件] [链接的目录/名称] #硬连接 注:cp -r 会把所有source当作普通文件(regular文件)&#x…

代码随想录算法训练营第35天 | 860.柠檬水找零 406.根据身高重建队列 452.用最少数量的箭引爆气球

柠檬水找零 局部最优&#xff1a;收到20元时优先找零10元5元&#xff0c;不够再找零3个5元&#xff0c;因为5元可以找零20和10&#xff0c;更有用。全局最优&#xff1a;完成所有的找零。 class Solution { public:bool lemonadeChange(vector<int>& bills) {int fi…

Flink问题解决及性能调优-【Flink rocksDB读写state大对象导致背压问题调优】

RocksDB是Flink中用于持久化状态的默认后端&#xff0c;它提供了高性能和可靠的状态存储。然而&#xff0c;当处理大型状态并频繁读写时&#xff0c;可能会导致背压问题&#xff0c;因为RocksDB需要从磁盘读取和写入数据&#xff0c;而这可能成为瓶颈。 遇到的问题 Flink开发…

多线程编程3——线程的状态

一、状态是线程的状态 状态是PCB中与调度相关的属性&#xff0c;线程是CPU调度执行的基本单位。所以&#xff0c;状态是线程的属性。谈到状态&#xff0c;考虑的都是线程的状态&#xff0c;不是进程&#xff01;&#xff01;&#xff01; 二、在Java中&#xff0c;线程的状态…

作业车间调度问题:P还是NP

获取更多资讯&#xff0c;赶快关注上面的公众号吧&#xff01; 文章目录 基本概念多项式时间指数时间 P问题&#xff08;多项式问题&#xff09;NP问题&#xff08;非确定性多项式问题&#xff09;暴力穷举法动态规划 P与NP关系&#xff1a;作业车间调度问题是典型的NP难问题 …

将vite项目(vue/react)使用vite-plugin-pwa配置为pwa应用,只需要3分钟即可

将项目配置为pwa模式&#xff0c;就可以在浏览器里面看到安装应用的选项&#xff0c;并且可以将web网页像app一样添加到手机桌面或者pad桌面上&#xff0c;或者是电脑桌面上&#xff0c;这样带来的体验就像真的在一个app上运行一样。为了实现这个目的&#xff0c;我们可以为vue…

vue3-hand-mobile

当我写完手势移动事件后&#xff0c;我又通过svg的方法添加了一段文字和polygon。当我在这个蓝色的polygon上滑动手势的时候&#xff0c;会报错。 可能这个bug只是我个人的代码导致的。但是我觉得vue3-hand-mobile插件的这一段代码写的有问题。 我通过circular-json库修复了这…

vite+vue3+ts项目上线docker 配置反向代理API

这次重点的坑是反向代理。 1。项目中配置代理&#xff0c;为了跨域请求数据 项目根目录中新建vite.config.ts文件 在文件中添加配置代理 注意&#xff1a;其中 /api 和target 的地址后面没有 / 2。在项目根目录中新建Httprequest.ts文件&#xff0c;引入axios&#xff0c;并…

网诺安全文件上传总结

一、文件上传简介 文件上传漏洞是指用户上传了一个可执行的脚本文件&#xff08;木马、病毒、恶意脚本、webshell等&#xff09;&#xff0c;并通过此脚本文件获得了执行服务器端命令的能力。上传点一般出现在头像、导入数据、上传压缩包等地方&#xff0c;由于程序对用户上传…

VUE使用computed实现子父组件双向绑定数据

上面字符串文字是父级的数据&#xff0c;下面表单是父级传给子组件并实现双向绑定 // 这里是vue3写法&#xff0c;vue2 同样在computed里写 get(){} 即可 const form computed({get(){ // props.modelForm 就是父级传过来的对象const proxy new Proxy(props.modelForm,{get(t…

网络原理——传输层2

1.TCP协议 TCP协议是工作中最常用到的协议。 TCP协议格式&#xff1a; 源端口号&#xff08;16位&#xff09;&#xff1a;源端口标识发送方的应用程序。目的端口号&#xff08;16位&#xff09;&#xff1a;目的端口标识接收方的应用程序。序列号&#xff08;32位&#xf…

echarts 堆叠柱状图数据差值较大,导致显示图形差异很大

问题描述&#xff1a; echarts 堆叠柱状图数据差值较大&#xff0c;导致显示图形差异很大 如图&#xff1a; 解决方案 柱状图、折线图 给 y轴或者x轴type设置log 就可以 。饼图 设置 minAngle

kafka summary

最近整体梳理之前用到的一些东西&#xff0c;回顾Kafka的时候好多东西都忘记了&#xff0c;把一些自己记的比较模糊并且感觉有用的东西整理一遍并且记忆一遍&#xff0c;仅用于记录以备后续回顾 Kafka的哪些场景中使用了零拷贝 生产者发送消息&#xff1a;在 Kafka 生产者发送…

使用.NET6 Avalonia开发跨平台三维应用

本文介绍在Vistual Studio 2022中使用Avalonia和集成AnyCAD Rapid AvaloniaUI三维控件的过程。 0 初始化环境 安装Avalonia.Templates dotnet new install Avalonia.Templates若之前安装过可忽略此步骤。 1 创建项目 选择创建AvaloniaUI项目 选一下.NET6版本和Avalonia版…

RX-8564 LC实时时钟模块

.内置 32.768 kHz 晶体单元(频率精度调整完毕) .接口类型&#xff1a;I2C-Bus 接口 (400 kHz) .工作电压范围&#xff1a;1.8 V ~ 5.5 V .计时&#xff08;保持&#xff09;电压范围 &#xff1a;1.0 V ~ 5.5 V / -20 ˚C ~70 ˚C .低待机电流 &#xff1a;275 nA / 3.0…