Tomcat线程池梳理

这篇具有很好参考价值的文章主要介绍了Tomcat线程池梳理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Tomcat梳理

1.问题

当Tomcat线程被打满时,可以按照以下步骤进行排查:

1. 查看Tomcat的日志文件,特别是错误日志。在日志中搜索关键字,比如"OutOfMemoryError",以确定是否存在内存溢出异常。
2. 检查Tomcat的JVM参数设置,尤其是内存相关的参数,如-Xmx和-Xms。确保这些参数适当设置,以满足应用的需求。如果需要增加内存,可以调整这些参数的值,并重新启动Tomcat。
3. 使用工具(如jmap、jstack等)获取Tomcat的内存快照和线程堆栈信息,以了解线程的状态和运行情况。这些信息可以帮助确定是否存在线程死锁或长时间运行的线程,从而引起了线程池被打满的问题。
4. 检查Tomcat的配置文件,特别是连接器(Connector)的配置。确保连接器的最大线程数(maxThreads)合理设置,可以根据实际需求适当增加或减少线程数。
5. 检查应用程序的代码,特别是与并发相关的代码块。确保没有出现死锁、线程安全问题或无限循环等导致线程被阻塞的情况。可以使用调试器或性能分析工具来定位问题代码段。
6. 监控服务器的系统资源使用情况,如CPU、内存、磁盘等。如果某个资源被耗尽,可能导致Tomcat线程被打满。可以使用监控工具,如Nagios、Zabbix等,来实时监测服务器资源的使用情况,并进行预警和调整。
7. 在Tomcat集群环境中,检查负载均衡器的配置和运行情况,确保请求能够均匀分发到各个Tomcat节点,避免某一节点负载过高。
8. 如果以上步骤仍然无法解决问题,可以尝试升级Tomcat版本或寻求Tomcat官方或社区的支持。他们可能能提供更具体的调试和排查建议。

总之,当Tomcat线程被打满时,需要综合考虑内存、线程、代码和系统资源等多个因素,并通过逐步排查来定位和解决问题。

2.监控tomcat线程池

springboot1.x

@Autowired
ServletWebServerApplicationContext applicationContext;

TomcatServletWebServerFactory tomcatServletWebServerFactory=applicationContext.getBean(TomcatServletWebServerFactory.class);
String tomcatLog = (((TomcatWebServer)(tomcatServletWebServerFactory.getWebServer())).getTomcat().getConnector()).getProtocolHandler().getExecutor().toString();

打印结果

org.apache.tomcat.util.threads.ThreadPoolExecutor@2a3ffb6f[Running, pool size = 10, active threads = 0, queued tasks = 0, completed tasks = 0]

springboot2.x

	@Autowired
	ServletWebServerApplicationContext applicationContext;
    
	String tomcatLog = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor().toString();

打印结果

org.apache.tomcat.util.threads.ThreadPoolExecutor@3a236dad[Running, pool size = 10, active threads = 1, queued tasks = 0, completed tasks = 0]

转为json格式打印输出

@RestController
public class DemoController {
    @Autowired
    ServletWebServerApplicationContext applicationContext;

    @GetMapping("/hs")
    public String test(){
        TomcatServletWebServerFactory tomcatServletWebServerFactory=applicationContext.getBean(TomcatServletWebServerFactory.class);
        String tomcatLog = (((TomcatWebServer)(tomcatServletWebServerFactory.getWebServer())).getTomcat().getConnector()).getProtocolHandler().getExecutor().toString();
        return tomcatLog;
    }


    @GetMapping("/hs2")
    public String test2(){
        String tomcatLog = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor().toString();
        return tomcatLog;
    }

    @GetMapping("/hs3")
    public String test3(){
        Executor executor = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor();
        return JSON.toJSONString(executor, SerializerFeature.WriteMapNullValue);
    }
}

打印结果

{
	"activeCount": 1,
	"completedTaskCount": 0,
	"corePoolSize": 10,
	"largestPoolSize": 10,
	"maximumPoolSize": 200,
	"poolSize": 10,
	"queue": [],
	"rejectedExecutionHandler": {},
	"shutdown": false,
	"submittedCount": 1,
	"taskCount": 1,
	"terminated": false,
	"terminating": false,
	"threadFactory": {},
	"threadRenewalDelay": 1000
}

3.SpringBoot内置线程解析测试

SpringBoot版本

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

controller

package com.kang.mongodb.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Executor;

/**
 * @Author Emperor Kang
 * @ClassName DemoController
 * @Description TODO
 * @Date 2023/8/21 19:59
 * @Version 1.0
 * @Motto 让营地比你来时更干净
 */
@Slf4j
@RestController
@RequestMapping("/tomcat")
public class TomcatController {
    @Autowired
    ServletWebServerApplicationContext applicationContext;

    /**
     * localhost:10093/tomcat/getString
     * @return
     */
    @RequestMapping("/getString")
    public String getString() {
        try {
            Executor executor = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor();
            log.info("{}-{}",Thread.currentThread().getName(), JSON.toJSONString(executor, SerializerFeature.WriteMapNullValue));
            // 将线程挂起3秒,方便观察结果
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "success";
    }

}

yaml配置

server:
  port: 10093
  tomcat:
    accept-count: 5        # 等待队列长度
    threads:
      min-spare: 10        # 最小工作空闲线程数
      max: 20              # 最大线程数
    max-connections: 30    # 最大连接数,一个线程可以处理多个连接

SpringBoot内置tomcat默认配置

SpringBoot内置Tomcat的配置存放在 spring-configuration-metadata.json 文件中,配置以 server.tomcat 开头

Tomcat线程池梳理,tomcat,tomcat,firefox,java

最小工作线程数

   {
      "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
    }
  • min-spare:最小备用
# 最小工作空闲线程数,默认10
server.tomcat.threads.min-spare=10

最大工作线程数

    {
      "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
    }
# 最大工作线程数,默认200
server.tomcat.threads.max=200

最大连接数

    {
      "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
    }

服务器在任何给定时间内接受和处理的最大连接数。一旦达到该限制,操作系统仍可根据 “acceptCount” 属性接受连接。

# 最大连接数默认是8192
server.tomcat.max-connections=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
    }

使用所有可能的请求处理线程时,接收到的连接请求的最大队列长度

# 等待队列长度,默认100
server.tomcat.accept-count=100

总结

参数 设置方式 默认值 含义
acceptCount server.tomcat.accept-count 100 接收队列,实质上是在操作系统已经完成三次握手等待accept的socket队列
maxConnections server.tomcat.max-connections 8192 最大连接数,实质上是指已经accept的socket数量
maxThreads server.tomcat.threads.max 200 用于处理已经accept的socket的线程最大数量
connectionTimeout server.tomcat.connection-timeout 60000ms 是指socket连接后或读取报文字节过程中的超时时间
keepAliveTimeout 实现WebServerFactoryCustomizer 默认取connectionTimeout 在同一个socket连接,处理完一次http请求后,等待下一次http请求的超时时间
MaxKeepAliveRequests 实现WebServerFactoryCustomizer 100 在同一个socket连接,最大处理http请求数量,达到数量后关闭socket

线程的生命周期

Tomcat线程池梳理,tomcat,tomcat,firefox,java

可知ThreadPoolExecutor有如下五种线程池状态。

  • RUNNING,线程池接受新任务,会执行任务阻塞队列中的任务,ctl前三位表示为111;
  • SHUTDOWN,线程池拒绝新任务,会执行任务阻塞队列中的任务,ctl前三位表示为000;
  • STOP,线程池拒绝新任务,不会执行任务阻塞队列中的任务,尝试中断正在执行的任务,ctl前三位表示为001;
  • TIDYING,所有任务被关闭,Worker数量为0,ctl前三位表示为010;
  • TERMINATED,terminated() 执行完毕,ctl前三位表示为011。
线程池 的状态 说明
RUNNING 允许提交并处理任务
SHUTDOWN 不允许提交新的任务,但是会处理完已提交的任务
STOP 不允许提交新的任务,也不会处理阻塞队列中未执行的任务,
并设置正在执行的线程的中断标志位
TIDYING 所有任务执行完毕,池中工作的线程数为0,等待执行terminated()勾子方法
TERMINATED terminated()勾子方法执行完毕

线程池监控指标

//获取webServer线程池
ThreadPoolExecutor executor = (ThreadPoolExecutor) ((TomcatWebServer) webServerApplicationContext.getWebServer())
        .getTomcat()
        .getConnector()
        .getProtocolHandler()
        .getExecutor();
Map<String, String> returnMap = new LinkedHashMap<>();
returnMap.put("核心线程数", String.valueOf(executor.getCorePoolSize()));
returnMap.put("最大线程数", String.valueOf(executor.getMaximumPoolSize()));
returnMap.put("活跃线程数", String.valueOf(executor.getActiveCount()));
returnMap.put("池中当前线程数", String.valueOf(executor.getPoolSize()));
returnMap.put("历史最大线程数", String.valueOf(executor.getLargestPoolSize()));
returnMap.put("线程允许空闲时间/s", String.valueOf(executor.getKeepAliveTime(TimeUnit.SECONDS)));
returnMap.put("核心线程数是否允许被回收", String.valueOf(executor.allowsCoreThreadTimeOut()));
returnMap.put("提交任务总数", String.valueOf(executor.getSubmittedCount()));
returnMap.put("历史执行任务的总数(近似值)", String.valueOf(executor.getTaskCount()));
returnMap.put("历史完成任务的总数(近似值)", String.valueOf(executor.getCompletedTaskCount()));
returnMap.put("工作队列任务数量", String.valueOf(executor.getQueue().size()));
returnMap.put("拒绝策略", executor.getRejectedExecutionHandler().getClass().getSimpleName());

并发测试

并发请求数 <= Tomcat最大线程数20

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

当请求量小于等于tomcat最大线程数时

  • 全部请求都正常,没有失败
  • 从结果可以看到越是靠后的线程,连接时间和处理时间都增长了,说明随着线程数增多性能下降了

tomcat线程池监控日志打印

Tomcat线程池梳理,tomcat,tomcat,firefox,java

http-nio-10093-exec-5-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-6-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-1-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-4-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-2-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-3-{"activeCount":6,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":10,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":6,"taskCount":6,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-8-{"activeCount":15,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":17,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":18,"taskCount":18,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-10-{"activeCount":16,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":16,"maximumPoolSize":20,"poolSize":16,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":16,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-7-{"activeCount":15,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":16,"maximumPoolSize":20,"poolSize":16,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":16,"taskCount":16,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-9-{"activeCount":16,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":16,"maximumPoolSize":20,"poolSize":16,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":17,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-14-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-13-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-11-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-12-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-15-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-17-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-16-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-18-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-19-{"activeCount":19,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":19,"maximumPoolSize":20,"poolSize":19,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":19,"taskCount":19,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-20-{"activeCount":20,"completedTaskCount":0,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":20,"taskCount":20,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
并发请求数 > Tomcat最大线程数20

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

当请求量大于tomcat最大线程数时

  • 可以看到前20个请求都在3s的时间左右完成了,但是后五个因为没有线程资源去处理只能等到这20个线程资源被释放后才能执行这几个线程,所以后面五个都是6s多才执行完成
  • 从聚合数据分析来看,我们如果不修改tomcat的配置,随着请求量的增多,系统的吞吐量是下降的

tomcat线程池监控日志打印

Tomcat线程池梳理,tomcat,tomcat,firefox,java

http-nio-10093-exec-4-{"activeCount":1,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":8,"taskCount":40,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-16-{"activeCount":4,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":14,"taskCount":46,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-17-{"activeCount":4,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":47,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-21-{"activeCount":12,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":15,"queue":[{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":47,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-18-{"activeCount":11,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":14,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":47,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-1-{"activeCount":16,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":16,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":16,"taskCount":49,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-24-{"activeCount":16,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":16,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":49,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-2-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-20-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-19-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-12-{"activeCount":4,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-13-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-22-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-26-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-25-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-27-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-23-{"activeCount":17,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":17,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":17,"taskCount":50,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-30-{"activeCount":20,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":24,"taskCount":57,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-28-{"activeCount":20,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":24,"taskCount":57,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-29-{"activeCount":20,"completedTaskCount":33,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":24,"taskCount":57,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-21-{"activeCount":16,"completedTaskCount":44,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":60,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-20-{"activeCount":16,"completedTaskCount":44,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":60,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-4-{"activeCount":16,"completedTaskCount":45,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":13,"taskCount":60,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-23-{"activeCount":17,"completedTaskCount":45,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":11,"taskCount":60,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-1-{"activeCount":17,"completedTaskCount":44,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":11,"taskCount":60,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}

挑几个典型的说说

Tomcat线程池梳理,tomcat,tomcat,firefox,java

  • poolSize:池中当前线程10,15,都已经达到最小空闲线程数的设置了,那么后面队列中排队的大小,就是加入队列等待处理的请求
  • submittedCount:提交的任务数,可以看到队列中有排队的,提交的任务数14,15,15,所以后面的五个必须要等到有线程资源的时候才可以去执行
并发请求数大于最大连接数:max-connections

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

并发请求数大于最大连接数:max-connections

  • 所有的请求都执行成功了,后面的15个请求都需要等待线程资源释放后才会去处理,所以从上面可以看到我们的处理时长后面的都是6S多
  • 有意思的是我们的吞吐量反而增加了,因为大量的线程被同时释放,所以大量排队的请求被处理了,从而增加了我们的吞吐量
  • 注意:连接是由线程去处理的,所以连接在等待线程,而不是线程等待连接(并发请求量大的时候)

tomcat线程池监控日志打印

Tomcat线程池梳理,tomcat,tomcat,firefox,java

http-nio-10093-exec-25-{"activeCount":3,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":8,"taskCount":91,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-26-{"activeCount":5,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":8,"taskCount":91,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-21-{"activeCount":5,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":10,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":8,"taskCount":91,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-16-{"activeCount":8,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":13,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":13,"taskCount":96,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-13-{"activeCount":8,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":13,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":14,"taskCount":97,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-1-{"activeCount":19,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":22,"taskCount":105,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-20-{"activeCount":19,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":22,"taskCount":105,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-4-{"activeCount":19,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":22,"taskCount":105,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-23-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-2-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-38-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-31-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-36-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-39-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-34-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-32-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-37-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-33-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-35-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-40-{"activeCount":20,"completedTaskCount":83,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":26,"taskCount":109,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-13-{"activeCount":20,"completedTaskCount":88,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":25,"taskCount":113,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-16-{"activeCount":20,"completedTaskCount":88,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":25,"taskCount":113,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-21-{"activeCount":20,"completedTaskCount":88,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":25,"taskCount":113,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-25-{"activeCount":20,"completedTaskCount":88,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":25,"taskCount":113,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-26-{"activeCount":20,"completedTaskCount":88,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":25,"taskCount":113,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-36-{"activeCount":18,"completedTaskCount":105,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":20,"taskCount":126,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-37-{"activeCount":20,"completedTaskCount":100,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":20,"taskCount":127,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-39-{"activeCount":20,"completedTaskCount":100,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":20,"taskCount":126,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-20-{"activeCount":20,"completedTaskCount":99,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{},{},{},{},{},{},{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":23,"taskCount":126,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-38-{"activeCount":16,"completedTaskCount":114,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[{}],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":14,"taskCount":133,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-33-{"activeCount":15,"completedTaskCount":122,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":137,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-4-{"activeCount":15,"completedTaskCount":122,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":137,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-31-{"activeCount":15,"completedTaskCount":122,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":137,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-34-{"activeCount":15,"completedTaskCount":122,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":137,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
http-nio-10093-exec-32-{"activeCount":15,"completedTaskCount":122,"corePoolSize":10,"largestPoolSize":20,"maximumPoolSize":20,"poolSize":20,"queue":[],"rejectedExecutionHandler":{},"shutdown":false,"submittedCount":15,"taskCount":137,"terminated":false,"terminating":false,"threadFactory":{},"threadRenewalDelay":1000}
并发请求数大于最大连接数+等待队列大小
  • 30+5=35

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

并发请求数大于最大连接数+等待队列大小

  • 我们请求量是45,但是我们tomcat能接收的最大请求为最大连接数+等待队列大小:30+5=35,所以我们发现有10个请求被拒绝了
  • Response code:Non HTTP response code: org.apache.http.conn.HttpHostConnectException
  • Response message:Non HTTP response message: Connect to 127.0.0.1:10093 [/127.0.0.1] failed: Connection refused: connect
  • 但是这种情况并不绝对,因为连接是由线程去处理的,因为每个请求过来肯定是尝试连接,一直尝试,我们可以看到,只有尝试时间很长的才失败了,但是很多尝试连接成功的,就被释放的线程资源去处理了,比如我把请求数设置40,结果如下

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java

  • 我们发现发起了40个请求,理论上应该是35个成功,5个失败,但是我们看到,他有这个尝试机制,只要连接成功了,并且有线程资源处理他就会执行返回

总结

  • 最大连接数:每个Http请求占用一个连接
  • 等待队列长度:Http请求数超过最大连接数时,多出的请求会放入等待队列,如果队列也满了请求会被丢弃。所以Tomcat能接收的请求数为最大连接数+等待队列长度
  • 最大线程数:Tomcat最多能同时处理的请求数,比如有30个请求,但是最大线程数为20,那么同时有20个请求可以被处理
  • 但是这种情况并不绝对,因为连接是由线程去处理的,因为每个请求过来肯定是尝试连接,一直尝试,我们可以看到,只有尝试时间很长的才失败了,但是很多尝试连接成功的,就被释放的线程资源去处理了,比如我把请求数设置40,结果如下

Tomcat线程池梳理,tomcat,tomcat,firefox,java

Tomcat线程池梳理,tomcat,tomcat,firefox,java文章来源地址https://www.toymoban.com/news/detail-665741.html

  • 我们发现发起了40个请求,理论上应该是35个成功,5个失败,但是我们看到,他有这个尝试机制,只要连接成功了,并且有线程资源处理他就会执行返回

总结

  • 最大连接数:每个Http请求占用一个连接
  • 等待队列长度:Http请求数超过最大连接数时,多出的请求会放入等待队列,如果队列也满了请求会被丢弃。所以Tomcat能接收的请求数为最大连接数+等待队列长度
  • 最大线程数:Tomcat最多能同时处理的请求数,比如有30个请求,但是最大线程数为20,那么同时有20个请求可以被处理

到了这里,关于Tomcat线程池梳理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Tomcat 配合虚拟线程,一种新的编程体验

    Java 21 在今年早些时候的 9 月 19 日就正式发布,并开始正式引入虚拟线程,但是作为 Java 开发生态中老大哥 Spring 并没有立即跟进,而是在等待了两个月后的 11 月 29 日,伴随着 Spring Boot 3.2 版本的发布,在这个版本中也终于是引入了对虚拟线程的支持。 虚拟线程的引入标志着

    2024年02月05日
    浏览(55)
  • 【仿写tomcat】六、解析xml文件配置端口、线程池核心参数

    上一篇文章中我们用了Excutors创建了线程,这里我们将它改造成包含所有线程池核心参数的形式。 主方法中对多线程操作部分改为使用CompletableFuture执行 现在我们有一个server.xml文件,我想解析其中的端口号以及线程池参数 如果想完成这个功能可以直接使用java本身自带的工具

    2024年02月12日
    浏览(30)
  • 【仿写tomcat】五、响应静态资源(访问html页面)、路由支持以及多线程改进

    如果我们想访问html页面其实就是将本地的html文件以流的方式响应给前端即可,下面我们对HttpResponseServlet这个类做一些改造 writeHtml这个方法将会读取webApp下面的html文件,注意只读取下面一级文件中的html文件,然后将这个文件以二进制流的形式转换成字符串拼接到上面定义的

    2024年02月12日
    浏览(44)
  • Spring Boot中内置Tomcat最大连接数、线程数与等待数 实践调优

    在 Spring Boot 框架中,我们使用最多的是Tomcat,这是 Spring Boot 默认的容器技术,而且是内嵌式的 Tomcat。Tomcat 是 Apache 基金下的一个轻量级的Servlet 容 器 , 支 持 Servlet 和 JSP 。Tomcat服务器本身具有Web服务器的功能,可以作为独立的Web服务器来使用。 Spring Boot 能支持的最大并发

    2024年02月12日
    浏览(43)
  • Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype

    目录 写一个控制层的类 验证方法 ​编辑 分别执行如下请求,先执行等待时间久的 日志结果 结论 配置多例模式 配置文件application.properties 类加注解 配置类方式 增加验证 控制层  服务层 都是  singleton 模式情况 模拟线程不安全情况 service 代码 ctr 测试方式 运行日志 结论

    2024年02月12日
    浏览(36)
  • TOMCAT部署及优化(Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

    TOMCAT tomcat :是一个开放源代码的web应用服务器,基于java代码开发的。也可以理解为tomacat就是处理动态请求和基于java代码的页面开发。可以在html当中写入java代码,tomcat可以解析html页面当中的java,执行动态请求,动态页面。 tomcat是机制存在一些问题,如果不对tomcat进行优化

    2024年02月13日
    浏览(31)
  • java:Tomcat

    在讲 Tomcat 是啥之前,我们先来了解一些概念。 服务器 可以理解为一个高性能的电脑,但是这个电脑现在什么软件都没有安装。 web 服务器 给这个服务器安装一些服务器软件,如 nginx、Apache、Tomcat 等。这台服务器就可以帮我们接收用户的请求,处理请求,做出响应。 Tomcat

    2024年02月11日
    浏览(37)
  • JAVA配置tomcat

    IDEA新建module的时候没有javaee的选项,这时候可以先选择普通的java项目进行创建。 图片中的a就是新建的java module。 右键a文件夹,选择Add Framework Support。 然后选中Web Application,点击右下角的ok即可。 a文件夹下出现带小蓝的web就说明成功了。 关联相关包 将jar包拷到libs文件夹下

    2023年04月08日
    浏览(40)
  • Tomcat:Java Web

    简介 Apache Tomcat 是 Java Web 应用程序开发中最为常用的服务器之一。作为一个开源、轻量级的 Servlet 容器和 JSP 容器,Tomcat 提供了一个稳定可靠的运行环境,使得开发者可以快速开发、部署和管理 Java Web 应用程序。本文将深入介绍 Tomcat 的特点、优势、安装、配置和基本用法,

    2024年03月23日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包