可观测性-Metrics-Tomcat连接数、线程数理解以及压测记录

news2024/12/28 18:58:54

文章目录

    • 背景
    • 原理
    • 压测
      • 5个并发压测
      • 10个并发压测
      • 60个并发压测
      • 61个并发压测

背景

为了搞懂Tomat的连接+线程模型,搞清楚每个配置参数的作用,实际压测看一下是否与预期一致。

Tomcat配置如下

server:
  # tomcat配置
  tomcat:
    # 允许最大连接数,默认8192,当达到临界值时,系统会基于accept-count继续接受连接
    max-connections: 50
    # 当所有线程都在使用时,建立连接的请求的等待队列长度,默认100
    accept-count: 10
    # 连接器在关闭空闲连接之前等待的毫秒数,默认 20000 20s
    connection-timeout: 20s
    uri-encoding: UTF-8
    threads:
      # 线程池的最小工作线程数,默认10
      min-spare: 5
      # 线程池的最大线程数,默认200
      max: 5
    mbeanregistry:
      # 是否启用Tomcat的MBean注册表
      enabled: true

测试接口伪代码

controller {
    /get
    String get(){
        Sleep(10s);
    }
}

原理

Tomcat的NioEndpoint实现了I/O多路复用模型。

Java的多路复用器的使用:

  • 创建一个Selector,在其上注册感兴趣的事件,然后调用select方法,等待感兴趣的事情发生
  • 感兴趣的事情发生了,比如可读了,就创建一个新的线程从Channel中读数据

NioEndpoint包含LimitLatch、Acceptor、Poller、SocketProcessor和Executor共5个组件。

img

此处来自:https://www.jianshu.com/p/eb1711261986

线程模型Tomcat源码如下

org.apache.tomcat.util.net.NioEndPoint.startInternal
- org.apache.tomcat.util.net.AbstractEndpoint.createExecutor
	- org.apache.tomcat.util.threads.ThreadPoolExecutor
	- org.apache.tomcat.util.threads.TaskQueue
	
AbstractEndpoint.java
public void createExecutor() {
    internalExecutor = true;
    TaskQueue taskqueue = new TaskQueue();
    // http-nio-8080-exec-
    TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
    // 这里的ThreadPoolExecutor是org.apache.tomcat.util.threads包下的。
    executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
    taskqueue.setParent( (ThreadPoolExecutor) executor);
}

  • Tomcat通过继承JDK的ThreadPoolExecutor实现自己的ThreadPoolExecutor,记录已提交但尚未完成的任务数 submittedCount

  • Tomcat自定义TaskQueue取代JDK中几种队列,配合上面的submittedCount,实现JDK线程池增强,实现新增线程池到Coresize -> maxSize -> queue.

  • server.tomcat.threads.maxserver.tomcat.threads.min-spare配置线程池。

maxConnections:最大连接数
这个参数是指tomcat能够接受的最大连接数。当Tomcat接收的连接数达到maxConnections时,Acceptor线程不会读取accept队列中的连接;这时accept队列中的线程会一直阻塞着,直到Tomcat接收的连接数小于maxConnections。如果设置为-1,则连接数不受限制。
默认值与连接器使用的协议有关:NIO的默认值是10000?8192,APR/native的默认值是8192,而BIO的默认值为maxThreads(如果配置了Executor,则默认值是Executor的maxThreads)。

(注意:在windows下,APR/native的maxConnections值会自动调整为设置值以下最大的1024的整数倍;如设置为2000,则最大值实际是1024。)
当连接数达到最大值maxConnections后,系统会继续接收连接,但不会超过acceptCount的值.

即Tomcat所能处理的最大连接数为 maxConnections + acceptCount

  • serverSock.socket().bind(addr,getAcceptCount());
  • LimitLatch作用也是对最大连接数的限制
org.apache.tomcat.util.net.AbstractEndpoint
private int maxConnections = 8*1024;
public void setMaxConnections(int maxCon) {
    this.maxConnections = maxCon;
    LimitLatch latch = this.connectionLimitLatch;
    if (latch != null) {
        // Update the latch that enforces this
        if (maxCon == -1) {
            releaseConnectionLatch();
        } else {
            latch.setLimit(maxCon);
        }
    } else if (maxCon > 0) {
        initializeConnectionLatch();
    }
}

再来个好理解的图:

Tomcat同时可以处理的连接数目是maxConnections,但服务器中可以同时接收的连接数为maxConnections+acceptCount 。acceptCount的设置,与应用在连接过高情况下希望做出什么反应有关系。如果设置过大,后面进入的请求等待时间会很长;如果设置过小,后面进入的请求立马返回connection refused。

总结下总体流程

启动时,Tomcat 将根据设置的值minSpareThreads创建初始线程,并根据需要增加线程数,直到maxThreads。 如果达到最大线程数,并且所有线程都忙,则服务器将只继续接受一定数量的并发连接maxConnections。一旦达到该限制,新连接将被放入队列 ( acceptCount) 中以等待下一个可用线程。当连接数达到maxConnections并且队列(acceptCount)已满时,任何额外的传入客户端将开始接收Connection Refused错误。

如果您的服务器开始生成这些错误,您将需要调整连接器的线程池容量以更好地适应传入请求的数量。

但是,请注意,如果您将最大线程数和最大队列长度 ( acceptCount) 的值设置得太高,则服务器流量的增加可能会快速消耗过多的服务器资源,因为它会填满队列并用完可用的线程数。

压测

Tomcat配置如下

压测的接口Sleep(10s)

server:
  # tomcat配置
  tomcat:
    # 允许最大连接数,默认8192,当达到临界值时,系统会基于accept-count继续接受连接
    max-connections: 50
    # 当所有线程都在使用时,建立连接的请求的等待队列长度,默认100
    accept-count: 10
    # 连接器在关闭空闲连接之前等待的毫秒数,默认 20000 20s
    connection-timeout: 20s
    uri-encoding: UTF-8
    threads:
      # 线程池的最小工作线程数,默认10
      min-spare: 5
      # 线程池的最大线程数,默认200
      max: 5

应关注的metrics

指标定义
tomcat.threads.busytomcat 繁忙线程
tomcat.threads.currenttomcat 当前线程数(包括守护线程)
tomcat.threads.config.maxtomcat 配置的线程最大数
tomcat.connections.current这个默认没有,补上。
tomcat.connections.max这个默认没有,补上。

connectionCount

org.apache.tomcat.util.net.AbstractEndpoint
- getConnectionCount

相关代码:https://gitee.com/lakernote/easy-admin

5个并发压测

期望:因为Tomcat配置的线程数刚好是5,所以RT都是10s左右

实际:RT都是10s左右

10个并发压测

期望:因为Tomcat配置的线程数刚好是5,会有5个连接排队等10s,所以RT应该是5个10s左右,5个20s左右。平均值为15s左右

实际:平均RT是15s左右

60个并发压测

期望:因为Tomcat配置maxConnections+acceptCount = 50 + 10 =60,应该刚好不会出现Connection Refused错误,但是有大量RT很长。

实际:没有错误。

当前连接数

61个并发压测

期望:因为Tomcat配置maxConnections+acceptCount = 50 + 10 =60,会出现一个Connection Refused错误,有大量RT很长。

实际:有一个错误。

参考:

  • https://www.datadoghq.com/blog/tomcat-architecture-and-performance/
  • https://www.cnblogs.com/sandyflower/p/15495419.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/65467.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

磁盘和文件系统管理(一)

检测并确认新硬盘 fdisk命令 查看或管理磁盘分区 fdisk -l [磁盘设备] 或 fdisk [磁盘设备] 交互模式中的常用指令 m、p、n、d、t、w、q d delete a partition * 删除分区 g create a new empty GPT partition table 创建一个新的空的GPT分区表(可以对大于2T磁盘进行分区) l…

Java - Object#finalize在JDK9中被标记废弃了!

Java - Object#finalize在JDK9中被标记废弃了! 时间:2022年12月6日01:34:10 目录: ① 为什么要废弃? ② 废弃后,使用什么方式主动监测对象是否被回收? 一、为什么要废弃? ⚡注意:废…

ChatGPT成精了!

最近几天,朋友圈、公众号都被 ChatGPT 刷屏了。 更有不少标题党吹嘘 “谷歌要完,百度也危了”。 那么它到底有没有网上吹的这么神奇呢? 我亲测了一把,感觉确实非常惊艳! 例如: 看着还不错,每…

20221206英语学习

今日新词: outwards adv.向外, 朝外 outrage n.义愤,愤慨;暴行,骇人听闻的事件 drown v.淹没, 溺死, 浸透, 浸泡 visit n.访问, 参观, 看望, 游览 setting n.环境, 背景, (戏剧、小说等的)情节背景&am…

面试题: Hive-SQL查询连续活跃登录用户思路详解

文章目录创造数据登录日志去重一、思路一1.1、分组排序1.2、日期减去计数值得到结果, 用户连续登陆情况下,每次相减的结果都相同1.3、根据 user_id 和 dis 分组,得到用户的 开始、结束时间、连续登录天数1.4、连续登录超过两天用户二、思路二&#xff1a…

【Rust日报】2022-12-05 探索 docker 的 WASM 技术预览

探索 docker 的 WASM 技术预览docker于近日发布了支持 WASM 容器的预览版本,本文带你体验使用 Rust 编写代码,并且编译成 WASM 最终运行于 docker 的过程.原文链接: https://medium.com/shyamsundarb/exploring-docker-hubs-wasm-technical-preview-76de28c3b1b4使用 Rust 破解…

Matlab学习——变量与档案存取

一、变量 1. char和string MATLAB里面的字符和字符串都是用单引号括起来的。 % 示例:aI like China; n0; for n1:1:size(a,2)b(size(a,2)-n1)a(n); end disp(a); disp(b);% 输出:>> work I like China anihC ekil I >> % 示例&#xff…

Dockerfile的常用指令和构建案例

一、Dockerfile操作常用的指令 (1) FROM 镜像 指定新镜像所基于的基础镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 (2) MAINTAINER 名字 说明新镜像的维护人信息 (3) RUN命令 在所基于的镜像上执行命令,并提交到新的…

B2B商城交易平台搭建方案为专用设备行业注入新动力,加快产业数字化转型升级

专用设备是指设备的结构、性能专门针对某一种或一类对象,实现一项或几项功能的工业,包括工程机械、光伏设备、锂电设备、3C设备、半导体设备等。近年来,受市场对专用设备的应用需求不断扩大、产业技术升级趋势加快等影响,我国专用…

直播回顾:Coremail校园邮件安全防护交流会暨新技术应用分享

11月23日,Coremail校园邮件安全防护交流会暨新技术应用分享直播举办。 Coremail作为国内TOP级邮件系统厂商,服务上百家高校,特邀以下重磅嘉宾参与了本次圆桌讨论。 本次圆桌会主要探讨校园典型钓鱼邮件防范与新技术在校园邮件中的应用。 高校…

mysql 查询在一张表不在另外一张表的记录

SQL Join子句,主要用在select语句中,把两个或多个表的行结合起来,基于这些表之间的共同字段(往往是id字段)来查询,从多个表中返回满足条件的所有行。 常见join子句类型 常见join子句类型有INNER JOIN(同JOIN)、LEFT JOIN、RIGHT…

【Java学习Note】第8章 多线程

8. 多线程 文章目录8. 多线程8.1 程序、进程、线程8.2 线程的创建8.2.1 继承Thread类-创建线程方法之一8.2.2 Thread常用方法8.2.3 实现Runnable接口-创建线程方法之二8.2.4 两种多线程的区别8.3 线程得调度8.4 线程的生命周期8.5 线程的同步8.5.1 线程同步--Synchronized8.5.2…

html网页设计与制作:基于html设计整套招聘网站求职前端模板页面 静态网页HTML代码 学生网页课程设计期末作业下载

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

联通边缘AI:打造“职业技能”,助力行业高质量发展

内容来源:2022年11月12日,由边缘计算社区主办的全球边缘计算大会上海站圆满落幕。我们非常荣幸邀请到了联通数科首席AI科学家廉士国博士来分享,廉博士是中国图像图形学会三维视觉专委会委员、IEEE智能计算及多媒体通信委员会委员、国家工业互…

WSL VSCode运行C++项目

WSL VSCode运行C项目collect2: error: ld returned 1 exit statusboost库的链接安装并编译boost库:链接库(!!这一步有错误,下面会改正)/usr/include/boost/python/detail/wrap_python.hpp:57:11: fatal error: pyconfig.h: No suc…

RK3588平台开发系列讲解(SARADC篇)SARADC的工作流程

平台内核版本安卓版本RK3588Linux 5.10Android12🚀返回专栏总目录 文章目录 一、SARADC驱动二、SARADC常用接口三、SARADC源码分析1、SARADC驱动注册2、用例分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍SARADC的源码分析和工作流程。 一、SARADC驱…

【Flink】需求实现之独立访客数量的计算 和 布隆过滤器的原理及使用

文章目录一 独立访客数量计算二 布隆过滤器1 什么是布隆过滤器2 实现原理(1)HashMap 的问题(2)布隆过滤器数据结构3 使用布隆过滤器去重一 独立访客数量计算 public static void main(String[] args) throws Exception{StreamExe…

Locust学习记录3-用户类属性【host attribute,tasks attribute】

host attribute(主机属性) host属性是家长主机的URL前缀(即“https://www.baidu.com”)。 这是在Locust的web UI 或命令行上指定的,在Locust【--host】启动时使用该选项 【--host】如果在用户类中声明了一个host属性,那么在命令…

答网友提问 - SAP Business Technology Platform(BTP) 的计费模式

我的知识星球 有朋友向我提问: S4HANA(本地部署或云版)跟SAP家族系统以及非SAP系统的集成,sap的标准/推荐做法是通过BTP还是直接连接,或者是根据目标系统分别选择?有参考链接最好了。 还有BTP的收费模式是什么样的,是不…

业聚医疗通过聆讯:上半年营收6885万美元 钱永勋为实控人

雷递网 雷建平 12月5日血管介入器械公司――业聚医疗集团有限公司(OrbusNeich Medical Group Limited)(简称“业聚医疗”)日前通过聆讯,准备在香港上市。上半年营收6885万美元业聚医疗总部位于中国香港,是一…