浅析Tomcat高并发之连接池,线程池
haoteby 2024-12-20 15:44 3 浏览
记得大学的《网络工程》有一个课后作业:用Java实现一个web服务器,当时想的是为了提高吞吐量,可以用多线程实现,即对于每一个客户端请求连接,都启动一个线程来处理,处理逻辑大概就是从socket里面读取http请求,解析执行请求,执行完把response写回socket,线程结束销毁。用多线程实现确实提高了吞吐量,但是也有一些问题:1)不断的线程创建销毁需要耗费大量的开销;2)线程之间的切换需要耗费很多开销;3)Java有创建最多线程数量的限制,具体可参考https://www.iteye.com/blog/jzhihui-1271122。
如果要优化上面的实现,可以怎么做呢?其实参考tomcat的发展进程,就是优化的方向。
1
Tomcat处理用户请求的入口组件叫做Connector,其有两个主要的实现:BIO(blocking io)和NIO(non-blocking io)。
简单讲,BIO的实现就是对上面多线程版本的一个改进,主要点在于把“每来一个连接启动一个线程处理”改成“每来一个连接都提交给线程池处理”。虽然线程池根据不同的配置,其工作行为会有所不同,但一般来讲,使用线程池的原则是:只需创建少量的线程就可以完成大量任务的执行,由于同时至多只有固定量的线程执行,剩余的任务会被放进queue里面缓冲起来,从这个角度看,这是一个典型的生产者-消费者模型。回到tomcat BIO,acceptor不断的接收连接,然后提交给线程池执行,acceptor就是生产者;线程池的每一个线程就是消费者,负责处理请求。
由于socket连接是长连接,连接的创建销毁也是很耗资源的,于是http协议增加了一个keep-alive header,这个header的意思是提示服务器端,在返回http response之后,不要断开socket,继续处理后续http请求,这样做的目的就是为了提高资源的可重用性。那么,对于tomcat BIO的实现,在keep-alive场景下,会有什么问题呢?如果一个线程处理的socket需要保持keep-alive,其在执行完一个http请求之后,需要阻塞在那里以等待下一个http请求,不能马上结束(直到timeout);在某些情况下,这样就可能存在大量的阻塞线程,新的连接不能被处理。
基于此,NIO就可以解决这个问题。NIO和BIO在请求处理部分的实现是一致的,都是基于线程池;不同的地方是:NIO的acceptor基于jdk nio实现,在收到一个连接之后,会把socketChannel注册到poller的selector上面,当socketChannel有数据可读时,poller就把此连接提交给线程池处理。回到上面keep-alive的场景,当一个线程处理完一个http请求之后,就可以马上结束,当前连接则回到selector继续监听接下来的http请求。所以,基于NIO的执行线程就不会出现基于BIO的阻塞情况。
NIO的核心在于selector,selector可以识别到已经ready的连接和没有ready的连接;在之前的一篇多线程文章(对比Java和.NET多线程编程)里面提到过,jdk的concurrency API有一个CompletionService类,就有点类似于nio的原理。
由于NIO天生的优势,tomcat从8.0版本开始就把NIO设成默认的Connector,而从8.5版本开始直接就把BIO去掉了。
2
在tomcat的官网有下面一段关于如何高并发处理请求的描述:
Each incoming request requires a thread for the duration of that request. If more simultaneous requests are received than can be handled by the currently available request processing threads, additional threads will be created up to the configured maximum (the value of the maxThreads attribute). If still more simultaneous requests are received, they are stacked up inside the server socket created by the Connector, up to the configured maximum (the value of the acceptCount attribute). Any further simultaneous requests will receive "connection refused" errors, until resources are available to process them.
- https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
个人觉得其没有反映出maxConnections这个参数的作用,所以应该是:如果maxConnections小于maxThreads,最大创建的线程数就是maxConnections的值,最大连接数也是maxConnections的值;但是如果maxConnections大于maxThreads,最大创建的线程数就是maxThreads的值,最大连接数则是maxConnections的值。
由于BIO和NIO底层实现的区别,配置maxConnections的值也需要区别考虑,这在maxConnections的默认值中就有所体现(对于BIO,maxConnections的默认值是maxThreads的值;而对于NIO,maxConnections的默认值则是10000):
3
上面有提到,tomcat接收处理请求的过程其实就是一个生产者-消费者模型,影响tomcat高并发的配置也可以首先分别从这两个方面考虑:
生产者
消费者
Queue
4
小结一下:
- 线程池的本质就是节省了不断创建销毁线程的开销;加上queue的使用,增加了一层缓冲,一定程度缓解了计算机的压力。当然线程池的配置,需要根据要处理的任务(CPU密集型还是io密集型)来仔细的考虑。
- Tomcat里面BIO和NIO的最大区别在于读取下一个请求时是否需要阻塞,这对于keep-alive的场景尤其重要,NIO可以大大提高吞吐量。
- 基于queue的生成者-消费者模型,也常常应用在系统架构层面,以缓冲生产者和消费者之间处理速度的gap,比如秒杀系统。
本文分享自微信公众号 - 天马行空布鲁斯(gh_2feda5c053bd)。
如有侵权,请联系 删除。
相关推荐
- 单点登录(SSO)解决方案介绍(单点登录概念)
-
一、单点登录的介绍单点登录(SingleSignOn),简称为SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系...
- 系统登录的三种方式,哪一种更安全?
-
登录是一个高频的动作,笔者抓住这一个小点,分析了系统登录的几种方式和对应的场景。今天谈谈登录。登录即用户输入用户名和密码登录进系统中。B端系统,对于登录的业务场景有两种(可能不止,目前遇到过这两种):...
- 到底什么是单点登录(SSO)?(什么叫做单点登录)
-
什么是单点登录?单点登录(SingleSign-On,简称SSO)是一种集中式的身份验证和授权机制,用户只需在一处输入一次凭证(例如用户名和密码)就可以访问多个相关但独立的软件系统。在数字化时代,...
- 5年稳如老狗的单点登录系统,到底是怎么搞出来的?
-
说到单点登录(SingleSign-On,简称SSO),大家的第一反应可能是——啊不就是登录一次,能到处串门儿嘛?别说,还真差不多,就是这么个意思。但真要搭一套好用、耐造、还能扛住公司里各种奇奇怪...
- 这些负载均衡都解决哪些问题?服务、网关、NGINX?
-
在微服务项目中,有服务的负载均衡、网关的负载均衡、Nginx的负载均衡,这几个负载均衡分别用来解决什么问题呢?一、服务的负载均衡先抛出一个问题:...
- Nginx负载均衡最全详解(4大算法原理机制)
-
Nginx在大型网站架构很重要,也是大厂重点考察方向,今天我就重点来详解Nginx负载均衡@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。Nginx负载均衡N...
- 负载均衡 Nginx Session 一致性(nginx 负载均衡 会话保持)
-
HTTPS请求跳转...
- 监控Oracle Cloud负载均衡器:Applications Manager释放最佳性能
-
设想你正在运营一个受欢迎的在线学习平台,在考试前的高峰期,平台流量激增。全球的学生同时登录,观看视频、提交作业和参加测试。如果OracleCloud负载均衡器不能高效地分配流量,或者后端服务器难...
- Nginx负载均衡:nginx.conf配置文件说明!
-
大家好,欢迎来到程序视点!我是你们的老朋友.小二!在此记录下Nginx服务器nginx.conf负载均衡的配置文件说明,部分注释收集与网络.关于nginx.conf基本的配置,请查看上一篇文章!Ng...
- Java高可用系统架构中的负载均衡策略
-
Java高可用系统架构中的负载均衡策略在现代的分布式系统中,负载均衡策略是构建高可用系统的基石。Java开发者需要深刻理解这些策略,以便打造稳定且高效的系统。接下来,让我们一起揭开负载均衡的神秘面纱。...
- Spring Boot3 客户端负载均衡全解析:从原理到实战
-
在当今互联网大厂后端技术开发的激烈竞争环境中,构建高效、稳定的微服务架构是核心诉求。其中,SpringBoot3作为热门开发框架,其客户端负载均衡功能对于提升系统性能、保障服务稳定性起着关键作用。...
- MySql高可用集群MySQL Router负载均衡读写分离
-
名词解释MGR:MysqlGroupReplication组复制,多台MySQL服务器在同一组中会自动保持同步状态,当某台服务器故障时,整个复制组依然可以保持正常并对外提供服务。...
- 性能测试之tomcat+nginx负载均衡(nginx tomcat)
-
nginxtomcat配置准备工作:两个tomcat执行命令cp-rapache-tomcat-8.5.56apache-tomcat-8.5.56_2修改被复制的tomcat2下con...
- win10/11双网卡链路聚合叠加负载均衡提升网速解决网卡网速瓶颈!
-
双网卡链路聚合一种网络配置技术,通过将多个物理网卡绑定在一起,形成一个逻辑上的网络接口,以提高网络的可靠性、可用性和性能。这种技术通常用于服务器和网络设备中,以实现负载均衡、冗余和高可用性。本机环境:...