Spring Boot内嵌Tomcat处理请求的链接数和线程数

news2024/11/14 13:31:52

Spring Boot内嵌Tomcat处理请求的连接数和线程数

处理请求的连接数和线程数配置

Spring Boot的配置项

#等待连接数
server.tomcat.accept-count=100
#最大链连接数
server.tomcat.max-connections=8192
#最小备用线程数
server.tomcat.threads.min-spare=10
#最大工作线程数
server.tomcat.threads.max=200

TomCat中的NIO模式的工作流程,主要分为Acceptor、Poller、Processor

Acceptor监听网络连接,有连接进来后注册在Poller中,Poller通过轮询检测连接中的读写事件,有事件发生时调用Processor进行请求处理。如下图:

Spring Boot内嵌Tomcat处理请求的链接数和线程数

源码说明(Spring Boot-2.7.18内嵌Tomcat-9.0.83)

线程数

线程数对应的是NIO模式图中的Executor,默认最大线程是200,核心线程数10。

  • server.tomcat.threads.min-spare 对应ThreadPoolExecutor的核心线程数
  • server.tomcat.threads.max 对应ThreadPoolExecutor的最大线程数
org.apache.tomcat.util.net.AbstractEndpoint
public void createExecutor() {
    internalExecutor = true;
    if (getUseVirtualThreads()) {
        executor = new VirtualThreadExecutor(getName() + "-virt-");
    } else {
    TaskQueue taskqueue = new TaskQueue();
    TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
        taskqueue.setParent( (ThreadPoolExecutor) executor);
    }
}

ThreadPoolExecutor就是Tomcat的NIO模式下创建的线程池,其中getMinSpareThreads()getMaxThreads()分别获取的是核心线程数和最大线程数,对应的就是server.tomcat.threads.min-spareserver.tomcat.threads.max

org.apache.tomcat.util.threads.TaskQueue

创建线程池的时候创建了一个TaskQueue,任务队列的处理逻辑主要在这里,下面分析一下TaskQueue的入队方法:

public boolean offer(Runnable o) {
    //1
    if (parent==null) {
        return super.offer(o);
    }
    //2
    if (parent.getPoolSizeNoLock() == parent.getMaximumPoolSize()) {
        return super.offer(o);
    }
    //3
    if (parent.getSubmittedCount() <= parent.getPoolSizeNoLock()) {
        return super.offer(o);
    }
    //4
    if (parent.getPoolSizeNoLock() < parent.getMaximumPoolSize()) {
        return false;
    }
    //5
    return super.offer(o);
}
  1. 如果parent(由 taskqueue.setParent( (ThreadPoolExecutor) executor)设置)属性为null,直接将任务添加到队列中等待执行
  2. 如果当前线程池中的活动线程数等于最大线程数,直接将任务添加到队列中等待执行
  3. 如果已提交但未开始执行的任务数小于或等于当前线程数,说明有足够的空闲线程来处理新任务,直接将任务添加到队列中等待执行
  4. 如果当前线程数大于最小线程数且小于最大线程数,需要创建新的线程来处理任务。返回false表示入队失败,ThreadPoolExecutor在检测到这种情况时会尝试创建一个新的线程来执行任务
  5. 线程池中有足够的资源或者队列尚未满时,直接将任务添加到队列中等待执行
org.apache.tomcat.util.threads.ThreadPoolExecutor

下面分析一下返回false的情况

public void execute(Runnable command, long timeout, TimeUnit unit) {
    submittedCount.incrementAndGet();
    try {
        //这个方法
        executeInternal(command);
    } catch (RejectedExecutionException rx) {
        if (getQueue() instanceof TaskQueue) {
            final TaskQueue queue = (TaskQueue) getQueue();
            try {
                if (!queue.force(command, timeout, unit)) {
                    submittedCount.decrementAndGet();
                    throw new RejectedExecutionException(sm.getString("threadPoolExecutor.queueFull"));
                }
            } catch (InterruptedException x) {
                submittedCount.decrementAndGet();
                throw new RejectedExecutionException(x);
            }
        } else {
            submittedCount.decrementAndGet();
            throw rx;
        }
    }
}
 private void executeInternal(Runnable command) {
     if (command == null) {
         throw new NullPointerException();
     }
     int c = ctl.get();
     //1
     if (workerCountOf(c) < corePoolSize) {
         if (addWorker(command, true)) {
             return;
         }
         c = ctl.get();
     }
     //2
     if (isRunning(c) && workQueue.offer(command)) {
         int recheck = ctl.get();
         if (! isRunning(recheck) && remove(command)) {
             reject(command);
         } else if (workerCountOf(recheck) == 0) {
             addWorker(null, false);
         }
     }
     else if (!addWorker(command, false)) {
         reject(command);
     }
 }
  1. 运行中的线程少于核心线程池大小(corePoolSize),尝试启动一个新线程,并将给定的任务作为其首个任务,如果成功则方法返回。
  2. 运行中的线程大于核心线程池大小(corePoolSize),检测线程池状态并执行入队操作。注意这里的workQueue就是在AbstractEndpoint.createExecutor()中构建ThreadPoolExecutor时注入的,如果 workQueue.offer(command) 入队成功,再次检查线程池的状态,确认是否需要撤销任务入队操作(如果线程池已经停止),或者启动一个新的非核心线程(如果当前没有工作线程)。
  3. 如果任务无法入队,即workQueue.offer(command)返回false的时候,则尝试添加一个新的非核心线程。如果失败,我们知道线程池要么已关闭,要么已饱和,因此拒绝该任务。
连接数

最大连接数对应的是NIO模式图中的Poller,用户请求进来后会注册到Poller中去,Poller可以处理的最大连接数就是server.tomcat.max-connections等待连接数对应的是NIO模式图中的Acceptor,在Acceptor中可以等待被accept方法调用返回的最大连接数就是server.tomcat.accept-count。如果accept方法执行的比较慢,短时间内大量请求的建立的TCP连接会被放在acceptCount定义大小的等待队列中,如果Poller可以处理的请求已达到最大值,并且不能及时处理完成,等待队列满了之后就会拒绝新的请求,并且没被及时处理的等待队列的TCP连接也会发出超时响应(connect timeout)。下面的方法一层层点击下去便会发现acceptCount影响的是C++层的TCP连接的队列大小。

    protected void initServerSocket() throws Exception {
        if (getUseInheritedChannel()) {
            //...省略
        } else if (getUnixDomainSocketPath() != null) {
            SocketAddress sa = JreCompat.getInstance().getUnixDomainSocketAddress(getUnixDomainSocketPath());
            serverSock = JreCompat.getInstance().openUnixDomainServerSocketChannel();
            serverSock.bind(sa, getAcceptCount());//这里获取
            //...省略
        } else {
            serverSock = ServerSocketChannel.open();
            socketProperties.setProperties(serverSock.socket());
            InetSocketAddress addr = new InetSocketAddress(getAddress(), getPortWithOffset());
            serverSock.bind(addr, getAcceptCount());//这里获取
        }
        serverSock.configureBlocking(true);
    }
一个类比图

Spring Boot内嵌Tomcat处理请求的链接数和线程数

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【git命令相关】git上传和删除文件步骤

&#xff08;一&#xff09;git登录 1. git bash窗口输入 git config --global user.name "你的Git账号" git config --global user. Email "你的Git邮箱"2. 生成密钥 ssh-keygen -t rsa -C "你的Git邮箱"在此命令执行的返回结果中找到key存放…

海康VisionMaster使用学习笔记11-VisionMaster基本操作

VisionMaster基本操作 VM示例方案 1. 工具拖拽及使用方式 分别从采集和定位栏里拖拽图像源,快速匹配,Blob分析工具 2. 模块连线 依次连线 3.如何订阅 点击快速匹配,可以看到输入源已订阅了图像1的图像,Blob分析类似 4. 方案操作及全局触发 点击快速匹配,创建特征模版,框选…

vue-cli搭建过程,elementUI搭建使用过程

vue-cli vue-cli 官方提供的一个脚手架&#xff0c;用于快速生成一个 vue 的项目模板&#xff1b;预先定义 好的目录结构及基础代码&#xff0c;就好比咱们在创建 Maven 项目时可以选择创建一个 骨架项目&#xff0c;这个骨架项目就是脚手架&#xff0c;我们的开发更加的快速。…

深兰科技荣获CFS第十三届财经峰会“2024杰出出海品牌引领奖”

近日&#xff0c;以“向新而行&#xff0c;新质生产力激发新活力”为主题的“CFS2024第十三届财经峰会暨Amazing 2024创新企业家节”在北京隆重开幕。峰会揭晓了第十三届“CFS 2024企业奖”的评选结果&#xff0c;深兰科技凭借自身在AI机器人出口和海外市场开拓等品牌全球化方面…

60KW~180KW一体式充电桩电路方案!

本次小编给大家带来了一款60KW~180KW的一体式充电桩电路方案&#xff0c;本方案包含接线图&#xff0c;电路原理图&#xff0c;PCB图&#xff0c;BOM&#xff0c;协议说明&#xff0c;产品标准等资料&#xff01; 下载链接&#xff01;https://t.1yb.co/KW1R 本方案采用STM32F…

std::wcout,std::cout控制台输出中文乱码,std::cerr字符串的字符无效

系列文章目录 文章目录 系列文章目录前言一、中文乱码原因二、解决方法1.如果是windos11下&#xff0c;使用英文语言&#xff0c;需要加以下代码2.如果是中文语言只需要一行关键代码3.如果在异常处理中显示宽字符中文4.完整代码如下&#xff1a;实现文件测试代码输出打印 前言 …

【图像特效系列】图像毛玻璃特效的实践 | 包含代码和效果图

目录 一 毛玻璃特效 1 代码 2 效果图 图像特效系列主要是对输入的图像进行处理,生成指定特效效果的图片。图像素描特效会将图像的边界都凸显出来;图像怀旧特效是指图像经历岁月的昏暗效果;图像光照特效是指图像存在一个类似于灯光的光晕特效,图像像素值围绕光照中心点呈…

极光推送(JPush)携手中大英才,打造智慧教育新模式

随着互联网技术的快速发展&#xff0c;在线教育行业蓬勃兴起&#xff0c;用户对学习体验的要求也越来越高。作为国内领先的职业技能知识培训服务商&#xff0c;中大英才(北京)网络教育科技有限公司(简称“中大英才”)始终致力于为多层次求知学习人士提供专业化、智能化和科学化…

实战演练:通过API获取商品详情并展示

实战演练&#xff1a;通过API获取商品详情并展示&#xff0c;通常涉及以下几个步骤&#xff1a;确定API接口、发送HTTP请求、处理响应数据、以及将数据展示给用户。这里我们以一个假想的商品详情API为例&#xff0c;使用Python语言和requests库来完成这个任务。 步骤 1: 确定A…

DMHS数据同步工具

DMHS数据同步工具 ​ 本章节主要介绍DM数据同步工具DMHS的使用&#xff0c;通过将oracle11g的数据同步到DM8的过程来理解DMHS的功能和作用。 安装前的准备 端口、服务信息 IP地址服务名称版本端口安装路径192.168.19.136OracleOracle11.0.21521/opt/oracle/DMHS源端dmhs_V3…

第100+22步 ChatGPT学习:概率校准 Platt Scaling

基于Python 3.9版本演示 一、写在前面 最近看了一篇在Lancet子刊《eClinicalMedicine》上发表的机器学习分类的文章&#xff1a;《Development of a novel dementia risk prediction model in the general population: A large, longitudinal, population-based machine-learn…

MapBox Android版开发 1 配置

MapBox Android版开发 1 配置 前言MapBox V9 配置创建工程配置地图配置私钥配置公钥配置仓库配置依赖配置权限地图初始化 显示地图布局文件地图Activity 运行效果 MapBox V11 配置创建工程配置地图配置私钥配置公钥配置仓库配置依赖配置权限 显示地图布局文件 运行效果 前言 本…

ee trade:黄金投资与股票投资的区别

黄金和股票&#xff0c; 是金融市场中两种常见的投资工具&#xff0c; 它们拥有截然不同的特点和风险&#xff0c; 了解它们的差异&#xff0c; 可以帮助投资者制定更合理的投资策略。 一、 投资性质&#xff1a; 避险与成长&#xff0c; 两种投资方向 黄金&#xff1a; 被视…

金价徘徊高位,市场聚焦美联储降息预期

现货黄金高位震荡 周二亚市早盘&#xff0c;现货黄金在2500美元/盎司关口附近徘徊&#xff0c;交投于2503.23美元/盎司附近。金价周一在创纪录的高位后出现回调&#xff0c;投资者从涨势中获利了结&#xff0c;并根据美联储的线索调整仓位&#xff0c;现货黄金最终收报2504.1…

Vue - 详细介绍 vue-monoplasty-slide-verify vue3-puzzle-vcode 滑动验证组件

Vue - 详细介绍 vue-monoplasty-slide-verify & vue3-puzzle-vcode 滑动验证组件 在日常的账号登录所需要的大部分是滑动验证来检验人为操作&#xff0c;免于字母验证码的繁琐输入&#xff0c;下面介绍在Vue2和Vue3中适用的滑动验证组件。 1、vue-monoplasty-slide-verif…

【GitLab】使用 Docker 安装 3:gitlab-ce:17.3.0-ce.0 配置

参考阿里云的教程docker的重启 sudo systemctl daemon-reload sudo systemctl restart docker配置 –publish 8443:443 --publish 8084:80 --publish 22:22 sudo docker ps -a 當容器狀態為healthy時,說明GitLab容器已經正常啟動。 root@k8s-master-pfsrv:~

远离内卷,新的跨境电商蓝海,智能小家电沃尔玛1P新赛道——WAYLI威利跨境助力商家

随着全球经济格局的变迁&#xff0c;跨境电商已经成为新的蓝海领域&#xff0c;其中智能小家电市场更是呈现出蓬勃的发展态势。在这样的背景下&#xff0c;沃尔玛1P会员凭借其独特的优势&#xff0c;正开辟出一条全新的跨境电商赛道。 一、智能小家电市场崛起&#xff0c;源于消…

通义灵码代码搜索功能的前沿性研究论文被软件工程国际顶会 FSE 录用

在今年 FSE 2024 软件工程大会上&#xff0c;阿里云通义灵码团队和重庆大学合作的论文《An Empirical Study of Code Search in Intelligent Coding Assistant: Perceptions, Expectations, and Directions》被 FSE Industry 2024 (CCF A) 录用。 本篇论文主要探讨了在智能编码…

告别硬件!试试ToDesk云电脑,让你的云端体验更有趣

在这个不断进步的数字时代&#xff0c;科技的每一次突破都在重新塑造我们的生活和工作模式。随着云计算技术的不断成熟&#xff0c;传统的硬件限制正在逐渐消失&#xff0c;一个全新的云端时代正悄然兴起。ToDesk云电脑作为这场变革的领航者&#xff0c;正引领我们进入一个更加…

海绵城市雨水监测系统简介

海绵城市雨水监测系统主要有&#xff1a;数据采集、无线数据传输、后台云服务、终端平台显示等部分组成。系统通过前端数据采集水质&#xff08;ss\cod\浊度、PH等&#xff09;、雨水雨量、流量、水位、土壤湿度、气象等数据。通过无线数据传输通讯&#xff08;4G、5G、以太网、…