前言


  • 最近看了很多tcp/ip 连接以及 IO相关的文章,但是依旧对数据库连接池等的部分不是很清楚, 所以这里仅是简单描述一下tomcat对应的http连接池数量的情况,不考虑与数据库的连接池的情况.

Linux内核相关


  • 周天时简单总结了下linux内核的两个参数.somaxconn以及tcp_max_sync_backlog.这两天又学习了解了下.发现这两个配置文件其实讲的是全连接以及半连接的队列, 但是真正开始进入数据传输时应该就已经不在这两个队列里面了. 如下图所示.

  • 所以前面两个参数应该是负责处理连接队列的,整整进入tomcat与client的交互时应该就不需要使用者两个队列了.核心就会变成其他的参数.
  • 这里我理解核心的参数应该是 1. 当前操作系统剩余内存能够支撑的tcp连接数, 2.nofile 当前进程能够打开的文件数减去程序已经加载的文件数. 比如我们springboot的项目如果有1000个jar包可能就会产生1000-2000个fd的连接数,加上日志,以及一些监听pid等文件nofile -2000 左右才是可以使用的tcp连接数
  • 这里 我的理解不一定正确, 我认为一个与tomcat 进行的tcp连接至少要占用一个文件描述符, 但是不清楚一个tcp连接复用多个http连接会不会占用更多的fd.

Tomcat相关


  • 还是回到之前的配置参数
server:
#tomcat配置
tomcat:
# 当所有线程都在使用时,建立连接的请求的等待队列长度,默认100
accept-count: 1000
# 线程池维持最小线程数,默认10
min-spare-threads: 4
# 允许最大连接数,默认10000,当达到临界值时,系统可能会基于accept-count继续接受连接
max-connections: 10000
# 最大线程数,默认200
max-threads: 1000
  • 这里进行解释:
max-thread:  应该就是 jstack-l 里面出现的 http 开头的thread信息, 随着threads 的数量的增加, 能够创建的线程会更多, 但是线程的创建和切换都是有成本的, 虽然线程能够共享进程的内存以及部分寄存器,但是上下文还是需要每次切换时进行switch,  线程多了切换的次数会变多,并且管理成本也比较高, 不建议设置的特别多,除非操作系统的cores 数特别多.
min-spare-threads: 这个参数可以应付在冷启动之后突然爆发的大量请求,避免一开会无法批量创建threads 时造成影响非常缓慢,建议可以保留一些. 需要注意的一点是 这两个线程都是 jvm 内部的线程, 内个现场都需要有 java的stack的size. 理论上默认值是 1m 左右, 可以设置为 256k 或者是更小 但是不能低于 172KB 还是一个具体的多大的数值, 但是如果栈空间过小, 会出现stack over flow的错误,并且递归的深度可能会不够, 不建议将栈空间设置的过小,毕竟会导致栈帧数量下降. 需要注意的另外一点,除非tomcat的http线程 还需要有类似于1. redis的连接线程. 2.gc线程. 3.数据库连接线程. 但是数据库的连接池好像不是在jvm的堆区和栈区管理的, 这一块需要找专家同事学习沟通一下. 我还没看到那一块内容. max-connections: 关于这个参数,可能需要专门说明一下, 因为linux有BIO NIO以及AIO等IO模型,一般的说法是,自从tomcat 7 之后已经不支持BIO模型了,BIO时 没一个线程只能为一个 connection服务, 会导致吞吐量下降的很厉害. NIO非阻塞的IO时, 因为在内核和网卡驱动这一块时是不需要thread等待的, 所以thread可以为其他进程服务, 所以这个时候thread可以为远远大于自己的connections 来提供服务, 但是需要注意的一点是,如果是高CPU 低IO的场景, connection 是thread 的比较高的倍数时就显得不太合适了, 只有IO占用较多资源和时间时可以将connection 数值设置的thread大很多, 默认值就是10000. 关于这个10000 我这里的理解时 如果没个connection的round time 都是10s 左右的话如果每个线程只需要有1s左右的线程计算时间,那么理论上1000个thread就可以提供服务了. 但是具体的算法需要参照源码,可能比我想象的要复杂很多. accept-count: 这个参数就会到了咱们内核参数里面的 somaxconn 参数对应了,就算这个参数可以设置的很大, 比如1000 但是实际上 具体的连接池大小是收到somaxconn和accept-count里面的较小值来决定的, 所以如果线程数较少,并且并发数产生了很多的连接数时很容易就会将max-connections 的数值打满,然后开始用accept-count的参数值,如果somaxconn是默认值的话 比如centos7 上面都是 128 那么第 10129个连接应该直接就会被linux 给drop 客户端返回connection reset 的提示信息 (自己推断的,还没明确实验)

IO相关


  • 最近有很多公众号在将linux的IO模型,最近一个月以来也看了很多内容,理解的不是很透彻, 这里简单总结一下.
IO有很多种类,磁盘是IO,键盘是IO,网络栈的收发其实也是IO操作.
因为CPU都是纳秒级别的反应, 网络的IO都是几十上百毫秒的延迟, 这里面有六七个数量级的延迟,为了不让CPU干耗着去等待缓慢的网络IO(机械磁盘IO也是如此),在最开始的blocked IO 基础之上 慢慢研发了NIO和AIO.
需要注意的是linux比较多的是NIO noblocked 但是AIO 也就是异步非阻塞IO实现的比较少一些.
阻塞和非阻塞IO的核心区别在于 在CPU获取到需要的IO数据之前 用户态的线程是在等待还是在干别的
如果在等待,那么就是阻塞IO,如果不等待而去干别的了 就是非阻塞IO.
CPU获取到数据之后,如果从内核态往用户态传输数据时是需要用户态线程参与的,就还是同步的
如果只是CPU将需要的IO数据复制到了用户态需要使用的地方,直接通知用户线程进行处理,那么就是异步的. 需要注意的是 linux还有一个zero copy的概念, 其实与内存里面的 copy on write 类似
都是避免不必要的内存读写,节约宝贵的总线带宽或者是内存带宽拉实现提高性能的操作. nginx 就使用了sendfile的方式进行 zero copy的机制来提高静态文件的传输速度, 记得能够减少一次内核态到用户态的文件copy,只是传递fd就可以让网卡直接传输client想服务器申请访问的资源. tomcat 作为 app server 感觉这一块不如 nginx这种io复用的纯web server 处理静态资源来的省时省力.
所以tomcat有一个handler 可以进行判断请求类型,如果是静态类型的话 交由一个类似的nginx web server 来处理,但是还是感觉会导致tomcat的负载变大, 建议还是前端静态文件还是专门有一个静态文件服务器来跑比较好一些.

疑惑的地方


  • springboot 开起来的进程之后线程数其实非常多,有redis的,有操作连接池的,也有tomcat用来实现http连接等的. 还有跟当前CPU数目一致数量的GC线程. 但是我一直不知道数据库连接池是如何管理的,虽然能在jstack 打开的thread 信息里面看到hikari pool 等的相关信息.但是感觉这些只是springboot 进行使用数据库连接池的进程,而不是管理数据库连接池的线程.
  • dump堆栈信息里面包含的内容,是否不包含native memory和method pool等. 以及连接池到底存放在何处,如何进行监控,如果单一个db多个app-server时 如果每一个app-server都保持一个比较多的数据量连接池,那么会不会对数据库服务器有较大的压力存在?

Springboot 内嵌Tomcat 的http连接池与thread的关系的更多相关文章

  1. 查看和指定SpringBoot内嵌Tomcat的版本

    查看当前使用的Tomcat版本号 Maven Repository中查看 比如我们需要查Spring Boot 2.1.4-RELEASE的内嵌Tomcat版本, 可以打开链接: https://mv ...

  2. SpringBoot内嵌Tomcat开启APR模式(运行环境为Centos7)

    网上查到的一些springboot内嵌的tomcat开启apr的文章,好像使用的springboot版本较老,在SpringBoot 2.0.4.RELEASE中已经行不通了.自己整理了一下,供参考. ...

  3. [Web Server]Tomcat调优之SpringBoot内嵌Tomcat源码分析

    以springboot:2.3.12.RELEASE中内嵌的tomcat-embed-core:9.0.46为例,进行分析 1 概述 1.0 关键依赖包 spring-boot-autoconfigu ...

  4. Spring Boot启动过程(五):Springboot内嵌Tomcat对象的start

    标题和上一篇很像,所以特别强调一下,这个是Tomcat对象的. 从TomcatEmbeddedServletContainer的this.tomcat.start()开始,主要是利用Lifecycle ...

  5. maven打包排除spring-boot内嵌tomcat容器依赖jar

    在pom文件中添加打包排除配置信息. <plugin> <artifactId>maven-war-plugin</artifactId> <version& ...

  6. springboot去除内嵌tomcat和打包在tomcat中运行需要做的步骤

    去除内嵌tomcat和添加jsp依赖 去除内嵌tomcat 在springboot启动依赖中去除内嵌tomcat <dependency> <groupId>org.sprin ...

  7. 如何优雅的关闭基于Spring Boot 内嵌 Tomcat 的 Web 应用

    背景 最近在搞云化项目的启动脚本,觉得以往kill方式关闭服务项目太粗暴了,这种kill关闭应用的方式会让当前应用将所有处理中的请求丢弃,响应失败.这种形式的响应失败在处理重要业务逻辑中是要极力避免的 ...

  8. 学习Tomcat(七)之Spring内嵌Tomcat

    前面的文章中,我们介绍了Tomcat容器的关键组件和类加载器,但是现在的J2EE开发中更多的是使用SpringBoot内嵌的Tomcat容器,而不是单独安装Tomcat应用.那么Spring是怎么和T ...

  9. c3p0、dbcp、tomcat jdbc pool 连接池配置简介及常用数据库的driverClass和驱动包

    [-] DBCP连接池配置 dbcp jar包 c3p0连接池配置 c3p0 jar包 jdbc-pool连接池配置 jdbc-pool jar包 常用数据库的driverClass和jdbcUrl ...

  10. 内嵌tomcat最简单用法

    maven项目引入内嵌tomcat依赖 <dependency> <groupId>org.apache.tomcat.embed</groupId> <ar ...

随机推荐

  1. 华为云应用服务网格最佳实践之从Spring Cloud 到 Istio

    摘要:在全球首届社区峰会IstioCon 2021中,华为云应用服务网格首席架构师张超盟发表了<Best practice:from Spring Cloud to Istio>主题演讲, ...

  2. 如何使用TCP/IP开发网络程序

    摘要:进行TCP协议网络程序的编写,关键在于ServerSocket套接字的熟练使用,TCP通信中所有的信息传输都是依托ServerSocket类的输入输出流进行的. 本文分享自华为云社区<Ja ...

  3. 云小课 | 使用ROMA API,API管理从此不用愁!

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:ROMA API致 ...

  4. 讲透学烂二叉树(五):分支平衡—AVL树与红黑树伸展树自平衡

    简叙二叉树 二叉树的最大优点的就是查找效率高,在二叉排序树中查找一个结点的平均时间复杂度是O(log₂N): 在<讲透学烂二叉树(二):树与二叉/搜索/平衡等树的概念与特征>提到 二叉排序 ...

  5. appuploader 常规使用登录方法

      转载:登录appuploader 登录appuploader   常规使用登录方法 双击appuploader.exe 启动appuploader 点击底部的未登录,弹出登录框 在登录框内输入ap ...

  6. 企业新道路怎么走?火山引擎AB测试助力决策选择

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   乐刻是一家创立8年的企业,除了消费者熟悉的乐刻健身房可办月卡.24小时营业等,其还有比外界了解更多元的业务.目 ...

  7. .NET Core 在其上下文中,该请求的地址无效。

    .NET Core 在其上下文中,该请求的地址无效. 看了端口,发现没被占用,后来发现是IP地址变了 改成正确的IP就可以了.

  8. AI Studio 基本操作

    https://aistudio.baidu.com/aistudio/projectdetail/6182202 项目启停 执行和调试 添加代码或文件 运行代码 %cd /home/aistudio ...

  9. VMware NAT 模式 虚拟机网络电缆被拔出,连不上网

    检查服务 VMnetDHCP,VMware NAT Service 服务是否已启动,启动后可以正常使用网络

  10. Could not autowire. No beans of 'RestTemplate' type found.

    解决方案 @Resourceprivate RestTemplate restTemplate;