SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

这篇具有很好参考价值的文章主要介绍了SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot开发最大的好处是简化配置,内置了Tomcat, 在SpringBoot2.0.x版本中内置Tomcat版本是8.5.x,SpringBoot内置Tomcat的默认设置中,Tomcat的等待队列长度默认是100,Tomcat的最小工作线程数默认分配10,Tomcat的最大线程数是200,最大连接数是10000,至于最大并发量和最大连接数,常常理解成最大并发量就是最大连接数,实际上是有些牵强的,最大连接数并不一定就是最大并发量。

SpringBoot内置Tomcat的包重要配置和类在

package org.springframework.boot.autoconfigure.web;
SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数
SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

内置的tomcat

SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

找到ServerProperties中的public static class Tomcat对象

package org.springframework.boot.autoconfigure.web;

…………

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
        //内容
}
SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

在public static class Tomcat中有很多配置


        /**
         * Maximum number of worker threads.
         */
        private int maxThreads = 200;

        /**
         * Minimum number of worker threads.
         */
        private int minSpareThreads = 10;

        /**
         * Maximum size, in bytes, of the HTTP post content.
         */
        private int maxHttpPostSize = 2097152;

        /**
         * Maximum size, in bytes, of the HTTP message header.
         */
        private int maxHttpHeaderSize = 0;

        /**
         * Whether requests to the context root should be redirected by appending a / to
         * the path.
         */
        private Boolean redirectContextRoot = true;

        /**
         * Whether HTTP 1.1 and later location headers generated by a call to sendRedirect
         * will use relative or absolute redirects.
         */
        private Boolean useRelativeRedirects;

        /**
         * Character encoding to use to decode the URI.
         */
        private Charset uriEncoding = StandardCharsets.UTF_8;

        /**
         * 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;

默认最大连接数maxConnections = 10000

默认队列长度acceptCount = 100

默认最大工作线程数maxThreads = 200

默认最小工作线程数 minSpareThreads = 10

也就是说配置如下

server.tomcat.accept-count = 100
server.tomcat.max-connections = 10000
server.tomcat.max-threads = 200
server.tomcat.min-spare-threads=10

在这里有个点儿

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
服务器在任何给定时间接受和处理的最大连接数。一旦达到限制,操作系统仍然可以根据“acceptCount”属性接受连接

也就是说当服务器已经达到最大连接数后,操作系统任然可以根据队列长度来接收连接

有时候我们通常会认为在默认配置下,最大并发量就是最大连接数,超过最大连接数10000后会出现tomcat拒绝连接的情况,触发的请求任务超过默认值200(最大线程数)+默认值100(等待队列长度)后,tomcat会拒绝处理请求任务

最大并发量,每个人都它的理解是不一样的

  1. 如果在乎tomcat运行能够同时处理的任务数量,那最大并发量可能理解成最大工作线程数(max-threads)---不包含队列里的数量(acceptCount)

  1. 如果在乎tomcat运行能够接纳的最大最多的任务数量,那最大并发量可以理解成最大连接数(max-connections)+队列长度的数量(accept-count) --- 包含队列里的数量(acceptCount)

通常对SpringBoot内置Tomcat调优主要是针对最大连接数(maxConnections = 10000),队列长度(acceptCount = 100),最大工作线程数(maxThreads = 200)和最小工作线程数 (minSpareThreads = 10)按需设置,一般根据服务器的性能(CPU)以及该程序可能面临的业务峰值(IO数据库等操作)进行参考调优。

测试一下SpringBoot内置Tomcat的最小工作线程和最大工作线程以及最大连接数和队列长度

我用的版本是SpringBoot2.0.5

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

简单编写一个http请求的Controller

package boot.example.web.tomcat.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

/**
 *  蚂蚁舞
 */
@Controller
@RequestMapping(value="/demo")
public class BootTomcatController {

    @Resource
    private BootTomcatService bootTomcatService;

    @RequestMapping(value="/test/{count}")
    @ResponseBody
    public String test(@PathVariable(name = "count", required = true) int count) throws InterruptedException {
        bootTomcatService.testTomcatThread(count);
        return "hello world " + count;
    }

}

处理业务的Service

package boot.example.web.tomcat.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 *  蚂蚁舞
 */
@Service
public class BootTomcatService {

    private final Logger log =  LoggerFactory.getLogger(this.getClass());

    void testTomcatThread(int count) throws InterruptedException {
        log.info(count+"");
        //Thread.sleep(40*1000);
    }
}

配置Tomcat的参数

server.port=8080

server.tomcat.accept-count = 2
server.tomcat.max-connections = 12
server.tomcat.max-threads = 6
server.tomcat.min-spare-threads=3

在这里,我把accept-count配置成2 把max-connections配置成12,把max-threads配置成6,min-spare-threads配置成3

新建一个测试线程

package boot.example.web.tomcat;

import cn.hutool.http.HttpRequest;

/**
 *  蚂蚁舞
 */
public class ThreadTest extends Thread {

    private final int count;
    public ThreadTest(int count){
        this.count = count;
    }

    public void run() {
        try {
            //  设置超时时间很大
            String result = HttpRequest.get("http://127.0.0.1:8080/demo/test/"+count).timeout(10000*1000).execute().body();;
            System.out.println(result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

这里用到hutool的http请求

<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.6</version>
</dependency>

启动的main方法

package boot.example.web.tomcat;

public class TestTomcat {

    public static void main(String[] args) {

        for (int i = 1; i < 30; i++) {
            ThreadTest test = new ThreadTest(i);
            test.start();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i);
        }
    }
}

启动SpringBoot Tomcat 然后启动测试的main方法 30次请求访问

控制台日志

SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

可以看到他的工作线程是3个,完全是符合server.tomcat.min-spare-threads=3的配置,而且线程数的使用没有达到最大线程数

假如我们把它的工作线程给临时阻塞着,故意让他达到最大线程数,40s时间

    void testTomcatThread(int count) throws InterruptedException {
        log.info(count+"");
        Thread.sleep(40*1000);
    }

如此的话运行程序 请求30次

可以看到控制台首先进入了6个请求,阻塞着处理任务,那么配置server.tomcat.max-threads = 6是生效的,等40s之后6个任务线程处理完了业务,接下来又是6个任务线程处理,再等40后还处理了2个任务线程,请求的次数30次 实际处理任务数加起来只有14次

SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

请求端日志(有报错)

SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

报错信息如下

Exception in thread "Thread-14" java.lang.RuntimeException: cn.hutool.core.io.IORuntimeException: ConnectException: Connection refused: connect
at boot.example.web.tomcat.ThreadTest.run(ThreadTest.java:24)
Caused by: cn.hutool.core.io.IORuntimeException: ConnectException: Connection refused: connect
at cn.hutool.http.HttpRequest.send(HttpRequest.java:1164)
at cn.hutool.http.HttpRequest.execute(HttpRequest.java:969)
at cn.hutool.http.HttpRequest.execute(HttpRequest.java:940)
at boot.example.web.tomcat.ThreadTest.run(ThreadTest.java:21)
Caused by: java.netCaused by: java.net.ConnectException: Connection refused: connect
at java.netat java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.netat java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.netat java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.netat java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.netat java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.netat java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.netat java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.netat java.net.Socket.connect(Socket.java:589)
at sun.netat sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.netat sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.netat sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.netat sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.netat sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.netat sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
at cn.hutool.http.HttpConnection.connect(HttpConnection.java:377)
at cn.hutool.http.HttpRequest.send(HttpRequest.java:1159)
... 3 more
14:18:57:25
Exception in thread "Thread-15" java.lang.RuntimeException: cn.hutool.core.io.IORuntimeException: ConnectException: Connection refused: connect
at boot.example.web.tomcat.ThreadTest.run(ThreadTest.java:24)
Caused by: cn.hutool.core.io.IORuntimeException: ConnectException: Connection refused: connect
at cn.hutool.http.HttpRequest.send(HttpRequest.java:1164)
at cn.hutool.http.HttpRequest.execute(HttpRequest.java:969)
at cn.hutool.http.HttpRequest.execute(HttpRequest.java:940)
at boot.example.web.tomcat.ThreadTest.run(ThreadTest.java:21)
Caused by: java.netCaused by: java.net.ConnectException: Connection refused: connect
at java.netat java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.netat java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.netat java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.netat java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.netat java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.netat java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.netat java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.netat java.net.Socket.connect(Socket.java:589)
at sun.netat sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.netat sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.netat sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.netat sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.netat sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.netat sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.netat sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
at cn.hutool.http.HttpConnection.connect(HttpConnection.java:377)
at cn.hutool.http.HttpRequest.send(HttpRequest.java:1159)
... 3 more

关键点在于

Caused by: cn.hutool.core.io.IORuntimeException: ConnectException: Connection refused: connect

也就是说30次请求,总共处理了14次请求,剩下的16次请求被tomcat给拒绝了----达到tomcat的最大能接纳的请求数后拒绝多余的请求连接。

SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数
SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数

30次请求进入tomcat后,16条被拒接,14条请求被处理,处理先是最大线程数max-threads=6,在处理的时候,有6条请求加上正在处理的6条满足最大连接数max-connections=12,在这里,还有2条,是accept-count=2配置的2条,这2条请求任务恰恰是最容易忽略的,如此最终处理了14条请求,也就是说tomcat拒绝请求的条件是大于了最大连接数+队列长度的数量。

这里的测试是在设置很大超时时间下进行的

timeout(10000*1000)

tomcat参数调优配置(和硬件本身的支撑有很大关系)

server.tomcat.min-spare-threads=10

默认最小的线程数10就可以,这个参数没有多大必要去配置,默认的已经很好了,建议配置范围10-50之间

server.tomcat.max-threads = 200

处理任务的最大线程数默认200,一般应用都是支持的,如果要优化看应用(写的程序)复不复杂,需不需要依托计算机的算力,也就是会不会大量消耗cpu,如果大量消耗cpu,那么这个max-threads不能设置过大,如果仅仅只是普通的入库查询操作,增删改查,max-threads可以设置大一些,但是也不能过大,过大会导致请求的响应变慢 ,建议设置在200-1200之间,大概是min-space-threads的20倍

server.tomcat.max-connections = 10000

最大连接线程数,这个值默认10000已经够大了,有时候真正的业务还没有达到这个值都已经要多服务部署了,因此该参数没有增大的必要,但是可以改小,改到max-thread的20倍左右

server.tomcat.accept-count = 100

至于队列中的默认100这个值,也满足需求了,非要改建议大于min-spare-threads小于max-threads之间的某个倍数值就可以,这个参数不能设置太小。

一般的请求都是有超时机制的,一个http请求,可能几十秒后都还没有得到数据,那就会自动超时,自动超时并不代表被tomcat拒绝,可能是tomcat还没有开始处理到它

这里记录一下SpringBoot内置Tomcat配置多端口启动

    @Bean
    public TomcatServletWebServerFactory getFactory() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        Connector[] connectors = this.connectors();
        if (connectors != null && connectors.length > 0) {
            tomcat.addAdditionalTomcatConnectors(connectors);
        }
        return tomcat;
    }

    private Connector[] connectors() {
        String ports = "8081,8082,8083,8084";
        if (StringUtils.isEmpty(ports)) {
            return null;
        }
        String[] port = ports.split(",");
        List<Connector> connectors = new ArrayList<>();
        for (String s : port) {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setPort(Integer.parseInt(s));
            connector.setScheme("http");
            //connector.setRedirectPort(8041);
            connectors.add(connector);
        }
        return connectors.toArray(new Connector[]{});
    }
15:16:08.692 spring-boot-logging [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
15:16:08.734 spring-boot-logging [restartedMain] INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
15:16:08.752 spring-boot-logging [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
15:16:08.754 spring-boot-logging [restartedMain] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
15:16:08.767 spring-boot-logging [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8081"]
15:16:08.773 spring-boot-logging [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8082"]
15:16:08.777 spring-boot-logging [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8083"]
15:16:08.782 spring-boot-logging [restartedMain] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8084"]
15:16:08.797 spring-boot-logging [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) 8081 (http) 8082 (http) 8083 (http) 8084 (http) with context path ''
15:16:08.802 spring-boot-logging [restartedMain] INFO boot.example.web.tomcat.AppTomcat - Started AppTomcat in 5.725 seconds (JVM running for 6.629)
Hello World!

这一条文章来源地址https://www.toymoban.com/news/detail-492659.html

Tomcat started on port(s): 8080 (http) 8081 (http) 8082 (http) 8083 (http) 8084 (http) with context path ''

到了这里,关于SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot内置Tomcat 配置和切换

    目录 SpringBoot内置Tomcat 配置和切换 基本介绍 内置Tomcat 的配置 application.yml配置 对上面代码解释一下方便理解 通过类来配置Tomcat 注销application.yml 对tomcat 配置,完成测试 切换WebServer, 演示如何切换成Undertow  修改pom.xml , 排除tomcat , 加入Undertow 包的依赖 运行项目,完成测试 S

    2024年02月06日
    浏览(44)
  • SpringBoot 内置 Tomcat 线程数优化配置

    本文解析springboot内置tomcat调优并发线程数的一些参数,并结合源码进行分析。 线程池核心线程数 server.tomcat.min-spare-threads :该参数为tomcat处理业务的核心线程数大小,默认值为10 线程池最大线程数 server.tomcat.max-threads :该参数为tomcat处理业务的最大线程数大小,默认值为2

    2024年02月09日
    浏览(44)
  • 关于磁盘空间不够,导致报错 springboot内置tomcat相关的临时目录无法创建等问题,如何自定义配置 tomcat 缓存文件路径

    关于磁盘空间不够,导致报错 springboot内置tomcat相关的临时目录无法创建等问题,如何自定义配置 tomcat 缓存文件路径 解决方法: shell 脚本命令:(配置自定义缓存路径参数 -Djava.io.tmpdir ) 注意: tmpPath 的绝对路径值必须是 / 斜杠结尾。 1. springboot内置tomcat相关的临时目录自

    2024年02月09日
    浏览(53)
  • tomcat如何调优,涉及哪些参数?

    Apache Tomcat 是一个开源的 Java Servlet 容器,用于部署和运行 Java Web 应用程序。为了提高 Tomcat 的性能和可伸缩性,可以对其进行调优。下面是一些常见的 Tomcat 调优参数和相关说明: 1.内存设置: -Xms: 设置 Java 虚拟机(JVM)的初始堆大小。 -Xmx: 设置 JVM 的最大堆大小。可以根据服

    2024年02月09日
    浏览(46)
  • openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优

    数据库提供两种手段进行并发队列的控制,全局并发队列和局部并发队列。 224.1 全局并发队列 全局并发队列采用GUC参数max_active_statements控制数据库主节点上运行并发执行的作业数量。采用全局并发队列机制将控制所有普通用户的执行作业,不区分复杂度,即执行语句都将作

    2024年02月22日
    浏览(49)
  • springboot-内置Tomcat

    一、springboot的特性之一 基于springboot的特性  自动装配@Configuretion 注解 二、springboot内置Tomcat步骤 直接看SpringApplication方法的代码块 总纲: 1、在SpringApplication.run 初始化了一个上下文ConfigurableApplicationContext configurableApplicationContext = AnnotationConfigServletWebServerApplicationContext,这里

    2024年02月15日
    浏览(40)
  • SpringBoot 源码分析(四) 内置Tomcat分析

    Tomcat文件的目录结构 启动一个Tomcat服务是执行的bin目录下的脚本程序, startup.bat 和 startup.sh .一个是windows的脚本,一个是Linux下的脚本,同样还可以看到两个停止的脚本 shutdown.bat 和 shutdown.sh . startup.bat 脚本内容 catalina.bat 脚本文件 doStart 方法 最后会执行的程序是 MAINCLASS 变量

    2024年02月08日
    浏览(40)
  • Springboot 优化内置服务器Tomcat优化(underTow)

    通过org.springframework.boot.autoconfigure.web.ServerProperties查看,其中包括属性tomcat、jetty、undertow三种服务器的设置,默认启用tomcat。 比较重要的有两个: 初始线程数 和 最大线程数 。 初始线程数: 保障启动的时候,如果有大量用户访问,能够很稳定的接受请求。 最大线程数: 用

    2024年02月04日
    浏览(50)
  • SpringBoot 最大连接数及最大并发数是多少?图解就看到了!

    在SpringBoot2.7.10版本中内置Tomcat版本是9.0.73,SpringBoot内置Tomcat的默认设置如下: Tomcat的连接等待队列长度,默认是100 Tomcat的最大连接数,默认是8192 Tomcat的最小工作线程数,默认是10 Tomcat的最大线程数,默认是200 Tomcat的连接超时时间,默认是20s 相关配置及默认值如下 当连接

    2024年04月17日
    浏览(31)
  • zookeeper版本选择与配置参数调优

    Apache ZooKeeper 社区一次支持两个发布分支:stable和current。ZooKeeper的稳定版本是 3.7.x,当前版本是 3.8.x。一旦发布新的次要版本,稳定版本预计将很快退役,大约半年后将宣布为 End-of-Life。在半年的宽限期内,预计只会为该版本发布安全和关键修复程序。宣布 EoL 后,社区不再

    2024年02月02日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包