当前位置: 首页 > news >正文

第四章-Tomcat线程模型与运行方式

🧵 第四章:Tomcat 线程模型与运行方式

目录

  • 4.1 线程模型概述
  • 4.2 支持的 I/O 模式
  • 4.3 线程生命周期管理
  • 4.4 运行模式详解
  • 4.5 性能对比分析
  • 4.6 配置优化建议
  • 4.7 本章小结

4.1 线程模型概述

4.1.1 线程模型架构

整体架构图
业务处理
Worker 线程池
Poller 线程
Acceptor 线程
Servlet 处理
业务逻辑
数据库操作
Worker 1
Worker 2
Worker 3
Worker N
Poller 1
Poller 2
Poller N
Acceptor
线程职责分工
线程类型职责数量生命周期
Acceptor接受新连接1个长期运行
Poller处理 I/O 事件1-2个长期运行
Worker处理业务逻辑可配置按需创建

4.1.2 线程池配置

标准线程池
// 标准线程池实现
public class StandardThreadExecutor implements Executor {private final ThreadPoolExecutor executor;private final String name;private final int maxThreads;private final int minSpareThreads;private final int maxSpareThreads;private final long keepAliveTime;public StandardThreadExecutor() {this.maxThreads = 200;this.minSpareThreads = 10;this.maxSpareThreads = 50;this.keepAliveTime = 60L;// 创建线程池this.executor = new ThreadPoolExecutor(minSpareThreads,           // 核心线程数maxThreads,                // 最大线程数keepAliveTime,             // 空闲时间TimeUnit.SECONDS,          // 时间单位new LinkedBlockingQueue<>(), // 工作队列new ThreadFactory() {      // 线程工厂private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix = "http-nio-8080-exec-";@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());t.setDaemon(false);t.setPriority(Thread.NORM_PRIORITY);return t;}});}@Overridepublic void execute(Runnable command) {executor.execute(command);}
}
自定义线程池
// 自定义线程池配置
public class CustomThreadExecutor implements Executor {private final ThreadPoolExecutor executor;public CustomThreadExecutor() {// 核心线程数int corePoolSize = 10;// 最大线程数int maximumPoolSize = 200;// 空闲时间long keepAliveTime = 60L;// 时间单位TimeUnit unit = TimeUnit.SECONDS;// 工作队列BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);// 线程工厂ThreadFactory threadFactory = new ThreadFactory() {private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix = "custom-exec-";@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());t.setDaemon(false);t.setPriority(Thread.NORM_PRIORITY);return t;}};// 拒绝策略RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);}
}

4.2 支持的 I/O 模式

4.2.1 BIO(阻塞 I/O)

特点
  • 阻塞模式:每个连接占用一个线程
  • 简单实现:代码逻辑简单,易于理解
  • 资源消耗:线程数量与连接数成正比
  • 适用场景:连接数较少,并发量不高的应用
实现原理
// BIO 连接器实现
public class Http11Protocol extends AbstractHttp11Protocol<Socket> {@Overrideprotected AbstractEndpoint.Handler<Socket> getHandler() {return new Http11ConnectionHandler(this);}
}// BIO 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<Socket, Http11Processor> {@Overrideprotected Http11Processor createProcessor() {Http11Processor processor = new Http11Processor(this);processor.setAdapter(getAdapter());return processor;}
}
配置示例
<!-- BIO 连接器配置 -->
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.2.2 NIO(非阻塞 I/O)

特点
  • 非阻塞模式:使用事件驱动模型
  • 高并发:少量线程处理大量连接
  • 复杂实现:需要处理事件循环和状态管理
  • 适用场景:高并发、长连接的应用
实现原理
// NIO 连接器实现
public class Http11NioProtocol extends AbstractHttp11Protocol<NioChannel> {@Overrideprotected AbstractEndpoint.Handler<NioChannel> getHandler() {return new Http11ConnectionHandler(this);}
}// NIO 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<NioChannel, Http11NioProcessor> {@Overrideprotected Http11NioProcessor createProcessor() {Http11NioProcessor processor = new Http11NioProcessor(this);processor.setAdapter(getAdapter());return processor;}
}
事件循环
// NIO 事件循环
public class Poller implements Runnable {private final Selector selector;private final AtomicBoolean running = new AtomicBoolean(true);@Overridepublic void run() {while (running.get()) {try {// 等待事件int keyCount = selector.select(selectorTimeout);if (keyCount > 0) {// 处理就绪的通道Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();// 处理 I/O 事件processKey(key);}}} catch (Exception e) {// 处理异常}}}private void processKey(SelectionKey key) {if (key.isReadable()) {// 处理读事件processRead(key);} else if (key.isWritable()) {// 处理写事件processWrite(key);}}
}
配置示例
<!-- NIO 连接器配置 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"maxConnections="8192" />

4.2.3 NIO2(AIO - 异步 I/O)

特点
  • 异步模式:真正的异步 I/O 操作
  • 回调机制:使用 CompletionHandler 处理结果
  • 系统支持:需要操作系统支持异步 I/O
  • 适用场景:高并发、异步处理的应用
实现原理
// NIO2 连接器实现
public class Http11Nio2Protocol extends AbstractHttp11Protocol<Nio2Channel> {@Overrideprotected AbstractEndpoint.Handler<Nio2Channel> getHandler() {return new Http11ConnectionHandler(this);}
}// NIO2 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<Nio2Channel, Http11Nio2Processor> {@Overrideprotected Http11Nio2Processor createProcessor() {Http11Nio2Processor processor = new Http11Nio2Processor(this);processor.setAdapter(getAdapter());return processor;}
}
异步处理
// 异步 I/O 处理
public class Http11Nio2Processor extends AbstractProcessorLight {@Overridepublic SocketState service(SocketWrapperBase<Nio2Channel> socketWrapper) throws IOException {// 异步读取socketWrapper.getSocket().read(inputBuffer, inputBuffer.position(), inputBuffer.remaining(), new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer result, Void attachment) {// 处理读取结果processRead(result);}@Overridepublic void failed(Throwable exc, Void attachment) {// 处理读取失败processError(exc);}});return SocketState.OPEN;}
}
配置示例
<!-- NIO2 连接器配置 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.2.4 APR(Apache Portable Runtime)

特点
  • 原生实现:使用 C 语言实现,性能更高
  • 系统优化:利用操作系统特性
  • 依赖库:需要安装 APR 库
  • 适用场景:对性能要求极高的应用
实现原理
// APR 连接器实现
public class Http11AprProtocol extends AbstractHttp11Protocol<Long> {@Overrideprotected AbstractEndpoint.Handler<Long> getHandler() {return new Http11ConnectionHandler(this);}
}// APR 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<Long, Http11AprProcessor> {@Overrideprotected Http11AprProcessor createProcessor() {Http11AprProcessor processor = new Http11AprProcessor(this);processor.setAdapter(getAdapter());return processor;}
}
配置示例
<!-- APR 连接器配置 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"connectionTimeout="20000"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100" />

4.3 线程生命周期管理

4.3.1 线程创建

线程工厂
// 自定义线程工厂
public class TomcatThreadFactory implements ThreadFactory {private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix;private final ThreadGroup group;private final boolean daemon;private final int priority;public TomcatThreadFactory(String namePrefix) {this(namePrefix, false, Thread.NORM_PRIORITY);}public TomcatThreadFactory(String namePrefix, boolean daemon, int priority) {this.namePrefix = namePrefix;this.daemon = daemon;this.priority = priority;this.group = Thread.currentThread().getThreadGroup();}@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement());t.setDaemon(daemon);t.setPriority(priority);return t;}
}
线程创建流程
// 线程创建流程
public class StandardThreadExecutor implements Executor {@Overridepublic void execute(Runnable command) {// 1. 检查线程池状态if (executor.isShutdown()) {return;}// 2. 提交任务executor.execute(command);}private void createWorkerThread(Runnable command) {// 1. 创建线程Thread worker = threadFactory.newThread(command);// 2. 设置线程属性worker.setDaemon(false);worker.setPriority(Thread.NORM_PRIORITY);// 3. 启动线程worker.start();}
}

4.3.2 线程调度

任务调度
// 任务调度器
public class TaskScheduler {private final ScheduledExecutorService scheduler;private final Map<String, ScheduledFuture<?>> tasks;public TaskScheduler() {this.scheduler = Executors.newScheduledThreadPool(1);this.tasks = new ConcurrentHashMap<>();}public void scheduleTask(String name, Runnable task, long delay, TimeUnit unit) {ScheduledFuture<?> future = scheduler.schedule(task, delay, unit);tasks.put(name, future);}public void scheduleAtFixedRate(String name, Runnable task, long initialDelay, long period, TimeUnit unit) {ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task, initialDelay, period, unit);tasks.put(name, future);}public void cancelTask(String name) {ScheduledFuture<?> future = tasks.remove(name);if (future != null) {future.cancel(false);}}
}
线程池监控
// 线程池监控
public class ThreadPoolMonitor {private final ThreadPoolExecutor executor;private final ScheduledExecutorService monitor;public ThreadPoolMonitor(ThreadPoolExecutor executor) {this.executor = executor;this.monitor = Executors.newScheduledThreadPool(1);// 启动监控startMonitoring();}private void startMonitoring() {monitor.scheduleAtFixedRate(() -> {// 监控线程池状态int activeCount = executor.getActiveCount();int poolSize = executor.getPoolSize();int corePoolSize = executor.getCorePoolSize();int maximumPoolSize = executor.getMaximumPoolSize();long completedTaskCount = executor.getCompletedTaskCount();long taskCount = executor.getTaskCount();// 记录监控信息log.info("ThreadPool Status: active={}, pool={}, core={}, max={}, completed={}, total={}",activeCount, poolSize, corePoolSize, maximumPoolSize, completedTaskCount, taskCount);}, 0, 30, TimeUnit.SECONDS);}
}

4.3.3 线程销毁

优雅关闭
// 优雅关闭
public class GracefulShutdown {private final ThreadPoolExecutor executor;private final long timeout;private final TimeUnit unit;public GracefulShutdown(ThreadPoolExecutor executor, long timeout, TimeUnit unit) {this.executor = executor;this.timeout = timeout;this.unit = unit;}public void shutdown() {// 1. 停止接受新任务executor.shutdown();try {// 2. 等待现有任务完成if (!executor.awaitTermination(timeout, unit)) {// 3. 强制关闭executor.shutdownNow();// 4. 再次等待if (!executor.awaitTermination(timeout, unit)) {log.warn("Thread pool did not terminate gracefully");}}} catch (InterruptedException e) {// 5. 中断当前线程executor.shutdownNow();Thread.currentThread().interrupt();}}
}
资源清理
// 资源清理
public class ResourceCleanup {private final List<AutoCloseable> resources;public ResourceCleanup() {this.resources = new ArrayList<>();}public void addResource(AutoCloseable resource) {resources.add(resource);}public void cleanup() {for (AutoCloseable resource : resources) {try {resource.close();} catch (Exception e) {log.error("Error closing resource", e);}}resources.clear();}
}

4.4 运行模式详解

4.4.1 独立运行模式

启动脚本
#!/bin/bash
# startup.sh# 设置环境变量
export CATALINA_HOME="/opt/tomcat"
export CATALINA_BASE="/opt/tomcat"
export JAVA_HOME="/opt/java"
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m"# 启动 Tomcat
exec "$CATALINA_HOME/bin/catalina.sh" run
停止脚本
#!/bin/bash
# shutdown.sh# 设置环境变量
export CATALINA_HOME="/opt/tomcat"
export CATALINA_BASE="/opt/tomcat"# 停止 Tomcat
exec "$CATALINA_HOME/bin/catalina.sh" stop
配置管理
<!-- 独立运行配置 -->
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /><Engine name="Catalina" defaultHost="localhost"><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><Context path="/myapp" docBase="myapp" /></Host></Engine></Service>
</Server>

4.4.2 内嵌运行模式

Spring Boot 集成
// Spring Boot 应用
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}// 自定义 Tomcat 配置
@Configuration
public class TomcatConfig {@Beanpublic TomcatServletWebServerFactory tomcatFactory() {return new TomcatServletWebServerFactory() {@Overrideprotected void postProcessContext(Context context) {// 自定义配置context.addParameter("app.config", "production");}};}
}
内嵌配置
// 内嵌 Tomcat 配置
public class EmbeddedTomcatConfig {public static void main(String[] args) throws Exception {// 创建 Tomcat 实例Tomcat tomcat = new Tomcat();tomcat.setPort(8080);// 设置基础目录tomcat.setBaseDir(".");// 添加上下文Context context = tomcat.addContext("/myapp", ".");// 添加 ServletTomcat.addServlet(context, "MyServlet", new MyServlet());context.addServletMappingDecoded("/myservlet", "MyServlet");// 启动 Tomcattomcat.start();tomcat.getServer().await();}
}

4.4.3 反向代理模式

Nginx 配置
# nginx.conf
upstream tomcat_backend {server 127.0.0.1:8080 weight=1;server 127.0.0.1:8081 weight=1;server 127.0.0.1:8082 weight=1;
}server {listen 80;server_name example.com;location / {proxy_pass http://tomcat_backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}location /static/ {alias /var/www/static/;expires 1y;add_header Cache-Control "public, immutable";}
}
负载均衡配置
// 负载均衡配置
public class LoadBalancerConfig {private final List<Server> servers;private final AtomicInteger currentIndex;public LoadBalancerConfig(List<Server> servers) {this.servers = servers;this.currentIndex = new AtomicInteger(0);}public Server getNextServer() {int index = currentIndex.getAndIncrement() % servers.size();return servers.get(index);}
}

4.5 性能对比分析

4.5.1 I/O 模式性能对比

性能测试结果
I/O 模式并发连接数响应时间吞吐量内存使用CPU 使用
BIO100050ms1000 req/s
NIO1000030ms5000 req/s
NIO21000025ms6000 req/s
APR1000020ms8000 req/s
性能分析
// 性能测试代码
public class PerformanceTest {public void testBIO() {// BIO 性能测试long startTime = System.currentTimeMillis();for (int i = 0; i < 1000; i++) {// 发送请求sendRequest();}long endTime = System.currentTimeMillis();System.out.println("BIO Time: " + (endTime - startTime) + "ms");}public void testNIO() {// NIO 性能测试long startTime = System.currentTimeMillis();for (int i = 0; i < 1000; i++) {// 发送请求sendRequest();}long endTime = System.currentTimeMillis();System.out.println("NIO Time: " + (endTime - startTime) + "ms");}
}

4.5.2 线程模型性能对比

线程数量对比
// 线程数量统计
public class ThreadCountMonitor {public void monitorThreads() {// 获取线程信息ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();int threadCount = threadBean.getThreadCount();int peakThreadCount = threadBean.getPeakThreadCount();long totalStartedThreadCount = threadBean.getTotalStartedThreadCount();System.out.println("Thread Count: " + threadCount);System.out.println("Peak Thread Count: " + peakThreadCount);System.out.println("Total Started Thread Count: " + totalStartedThreadCount);}
}
内存使用对比
// 内存使用监控
public class MemoryMonitor {public void monitorMemory() {MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();System.out.println("Heap Used: " + heapUsage.getUsed() / 1024 / 1024 + "MB");System.out.println("Heap Max: " + heapUsage.getMax() / 1024 / 1024 + "MB");System.out.println("Non-Heap Used: " + nonHeapUsage.getUsed() / 1024 / 1024 + "MB");}
}

4.6 配置优化建议

4.6.1 线程池优化

核心参数配置
<!-- 线程池优化配置 -->
<Connector port="8080" protocol="HTTP/1.1"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"connectionTimeout="20000"keepAliveTimeout="60000"maxKeepAliveRequests="100" />
参数说明
参数说明推荐值调优建议
maxThreads最大线程数200-500根据 CPU 核心数调整
minSpareThreads最小空闲线程数10-50保证快速响应
maxSpareThreads最大空闲线程数50-100避免资源浪费
acceptCount等待队列长度100-200根据并发量调整
connectionTimeout连接超时时间20000ms根据网络环境调整
keepAliveTimeout保持连接时间60000ms根据应用特性调整

4.6.2 内存优化

JVM 参数配置
# JVM 参数优化
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
参数说明
参数说明推荐值调优建议
-Xms初始堆大小512m与 -Xmx 相同
-Xmx最大堆大小1024m-2048m根据应用需求调整
-XX:PermSize永久代初始大小128mJava 8 之前使用
-XX:MaxPermSize永久代最大大小256mJava 8 之前使用
-XX:MetaspaceSize元空间初始大小128mJava 8 及以后使用
-XX:MaxMetaspaceSize元空间最大大小256mJava 8 及以后使用

4.6.3 系统优化

系统参数配置
# 系统参数优化
# 文件句柄数
ulimit -n 65536# 网络参数
echo 'net.core.somaxconn = 65536' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65536' >> /etc/sysctl.conf# 应用参数
sysctl -p
参数说明
参数说明推荐值调优建议
ulimit -n文件句柄数65536根据连接数调整
somaxconn监听队列长度65536提高并发处理能力
netdev_max_backlog网络设备队列长度5000提高网络处理能力
tcp_max_syn_backlogTCP 连接队列长度65536提高 TCP 处理能力

4.7 本章小结

关键要点

  1. 线程模型

    • Acceptor 线程:接受新连接
    • Poller 线程:处理 I/O 事件
    • Worker 线程:处理业务逻辑
  2. I/O 模式

    • BIO:阻塞 I/O,简单但性能较低
    • NIO:非阻塞 I/O,高并发处理
    • NIO2:异步 I/O,真正的异步处理
    • APR:原生实现,性能最高
  3. 运行模式

    • 独立运行:传统部署方式
    • 内嵌运行:Spring Boot 集成
    • 反向代理:Nginx + Tomcat 架构
  4. 性能优化

    • 合理配置线程池参数
    • 优化 JVM 参数
    • 调整系统参数

选择建议

  1. 开发环境:使用 NIO 模式,配置简单
  2. 测试环境:使用 NIO 模式,性能适中
  3. 生产环境:使用 APR 模式,性能最优
  4. 高并发场景:使用 NIO2 模式,异步处理

下一步学习

在下一章中,我们将深入探讨 Tomcat 的配置体系与部署机制,了解各种配置文件的用途和配置方法,以及如何实现自动化部署和运维管理。


相关资源

  • Tomcat 线程模型文档
  • NIO 编程指南
  • Spring Boot 内嵌 Tomcat
http://www.dtcms.com/a/523826.html

相关文章:

  • 【PB案例学习笔记】-46在数据窗口中编辑数据
  • tomcat问题
  • 爱电影网站个人养老金制度将落地
  • 自己做游戏网站电子商务营销是什么意思
  • 基于深度学习的短视频内容理解与推荐系统_hadoop+flask+spider
  • unbuntu系统配置IPV6的三种模式
  • ZVD振动抑制方法原理介绍
  • Java微服务无损发布生产案例
  • Kivy 乒乓游戏教程 基于Minconda或Anconda 运行
  • 摄影的网站设计特点同城发广告的平台有哪些
  • 【Python高级编程】类和实例化
  • 徐州市建设局交易网站网站设计的公司运营接单
  • 虹科亮相2025嵌入式会议 | 解读CAN XL与TSN如何驱动下一代E/E架构创新
  • VxWorks系统下龙芯平台的PCI驱动与硬件配置
  • 【2026计算机毕业设计】基于Django的新闻资讯平台的设计与实现
  • Linux小课堂: 基于 SSH 的安全文件传输与增量同步机制深度解析之从 wget 到 rsync 的全流程实战
  • 使用ffmpeg裁剪视频
  • 凡科建站网站西安全网推广公司
  • 免费网站建设程序下载建站用什么工具
  • 香港科技大学工学院2026/2027年度研究生课程招生宣讲会-重庆大学专场
  • Qualcomm SNPE(Neural Processing SDK)集成到 OpenWRT + QCS6490 的完整配置指南
  • LangGraph 官方教程:聊天机器人之一
  • Git与Gitee使用中的几个问题
  • 关于淘宝店网站建设的可行性报告网站建设的公司
  • Flink DatastreamAPI详解(四)
  • 线性代数直觉(四):找到特征向量
  • iis网站服务器 建立出现问题微信小程序制作费用是多少
  • 亚马逊云代理商:2025 AWS 服务器配置趋势走向怎么样?
  • 建设银行网站修改手机号湖南省和城乡住房建设厅网站
  • 云电脑与云手机的关系