[转帖] 在Linux上查看活跃线程数与连接数

linux,查看,活跃,线程,连接数 · 浏览次数 : 0

小编点评

**文章简介:** 文章介绍了如何查看和分析 Java 应用中的线程池和连接池的使用情况,并提供了用于获取这些信息的命令。 **主要内容:** * 使用 `top` 命令可以查看 java 进程的线程情况,其中包括线程名称、CPU 使用率等信息。 * 使用 `ss` 命令可以获取连接池的活跃情况,包括连接数量、本地监听端口等信息。 * 使用 `vmtool` 工具可以获取 Java 应用中的线程池和连接池的具体配置参数,例如最大连接数量、线程池大小等。 **获取活跃线程数和连接池大小的步骤:** 1. 使用 `vmtool` 获取应用中的 `DruidDataSource` 和 `PoolingHttpClientConnectionManager` 对象。 2. 使用 `vmtool` 获取每个连接池的配置参数,例如最大连接数量、等待线程数量等。 3. 使用 `vmtool` 获取每个线程池的配置参数,例如最大线程数量、队列大小等。 4. 将这些配置参数汇总到一个字典中,其中键值对应对应配置参数的名称。 5. 使用 `vmtool` 获取应用中所有线程池和连接池的配置,并将其存储在一个字典中。 6. 遍历这个字典,并统计每个线程池和连接池的活跃线程数量。 **示例命令:** 获取 Druid 连接池的活跃线程数: ```bash vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className com.alibaba.druid.pool.DruidDataSource --express 'instances.{ #{\"url\":#this.getUrl().split(\"\\\\?\")[0], \"username\":#this.getUsername(),\"PoolingCount\":#this.getPoolingCount(),\"ActiveCount\":#this.getActiveCount(),\"MaxActive\":#this.getMaxActive(),\"WaitThreadCount\":#this.getWaitThreadCount(),\"MaxWaitThreadCount\":#this.getMaxWaitThreadCount()} }' -x 2 ``` 获取 HTTP Client 连接池的活跃线程数: ```bash vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.apache.http.impl.conn.PoolingHttpClientConnectionManager --express 'instances.{ #pool=#this.pool.routeToPool.values() }' -x 2 ```

正文

https://www.cnblogs.com/codelogs/p/17178675.html

 

 

原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。

简介#

现如今,有两种常见的软件资源几乎成了Java后端程序的标配,即线程池与连接池,但这些池化资源非常的重要,一旦不够用了,就会导致程序阻塞、性能低下,所以有时我们需要看看它们的使用情况,以判断这里是否是瓶颈。

查看活跃线程数#

在Linux上,通过top -H -p 1命令,可以查看java进程的线程情况,其中1是java进程号,如下:
image_2023-03-04_20230304140014
如上,可以看到线程的名称、CPU使用率等,其中http-nio-8080-e就是Tomcat线程池中的线程,tomcat线程全名类似于http-nio-8080-exec-20,由于Linux中线程名称有长度限制,所以被截断了。

注:jdk8的话,需要jdk8u222以上版本,才能在top中看到线程名称。

我们数一下http-nio-8080-e线程的数量,发现它有20个,正好对应上了在springboot中的线程配置。
image_2023-03-04_20230304133328

这样能通过top得到线程池的线程数量了,但如何了解线程池的使用情况,即活跃线程有多少个呢?

经过查看man文档,我发现top命令有一个-i选项,描述如下:
image_2023-03-04_20230304134557
意思就是i是一个开关选项,默认会显示全部线程,而打开此选项之后,就只显示活跃线程了!

所以,只需要利用-i选项,再配合sed/awk/uniq等文本处理命令,即可以统计出活跃线程数了,如下:

$ top -H -i -b -d 1 -n2 -p 1 | awk -v RS= 'END{print $0}' | awk '$1 ~ /[0-9]+/{print $12}' | sed -E 's/[0-9]+/n/g' | sort | uniq -c

image_2023-03-04_20230304141731
可以看到,20个线程的线程池中,在1秒内只有4个线程是活跃的,线程池中线程数量是足够的。

这个命令脚本就不展开解释了,也不复杂,有linux命令基础的将命令依次拆开执行,应该能Get到脚本逻辑,没学过linux命令的话,就直接拿去用吧😅

查看活跃连接数#

在Linux上,使用ss -natp|grep pid=1可以查看1号进程的TCP连接,如下:
image_2023-03-04_20230304144050
比如若redis数据库端口是6379的话,那么可这样查看redis连接池中连接数量,如下:

$ ss -natp | grep pid=1 | awk '$5~/:6379$/' | wc -l
20

可见当前有20个redis网络连接,那同样的,其中有多少个是活跃的呢?

经过查看man文档,发现ss中也有一个-i选项,如下:
image_2023-03-04_20230304145652
可以发现,添加-i选项后,ss会输出tcp连接中的一些额外信息,其中lastsnd表示最后一次发送包到当前所经历的毫秒数,lastrcv表示最后一次接收包到当前所经历的毫秒数。

有了这个信息后,就可以通过awk过滤出lastsnd或lastrcv小于1000的tcp连接,这些连接即是1秒内活跃过的连接了,因此我又编写了如下命令脚本。

$ ss -natpi | sed '1!{N;s/\n//;}' | grep pid=1 | awk -v t=1000 'match($0,/lastsnd:(\w+) lastrcv:(\w+)/,a) && (a[1]<t || a[2]<t) && match($4,/(.+):(\w+)$/,s) && match($5,/(.+):(\w+)$/,d) && s[2]>=32768{print d[2]}' |sort |uniq -c |sort -nk2
      8 80
      3 3306
      7 3307
      6 6379
      1 7916

如上,可以看到各连出端口的活跃连接情况,其中80是http连接池端口,3306与3307是MySQL主从库的连接池端口,6379是redis连接池的端口。

这是java应用主动连出连接的活跃情况,那调用方连入java应用的呢?

其实只需要稍微调整一下awk脚本即可,如下:

  1. s[2]>=32768调整为s[2]<32768,其中32768是Linux默认的临时端口号的分界线,可通过sysctl net.ipv4.ip_local_port_range查询,本地端口号大于这个值,代表是连出连接.
  2. print d[2]调整为print s[2],和上面条件联合起来,输出的就是本地监听端口了.

调整后,效果如下:

$ ss -natpi | sed '1!{N;s/\n//;}' | grep pid=1 | awk -v t=1000 'match($0,/lastsnd:(\w+) lastrcv:(\w+)/,a) && (a[1]<t || a[2]<t) && match($4,/(.+):(\w+)$/,s) && match($5,/(.+):(\w+)$/,d) && s[2]<32768{print s[2]}' |sort |uniq -c |sort -nk2
     8 8080

可以发现,我们服务的8080端口,1秒内活跃过的连接数是8个。

注:只有当调用方也使用连接池时,这种方法获取到的活跃连接数才是准确的,若调用方使用短链接的话,则不准确。

arthas查看活跃线程数与连接数#

通过上面的方法,已经可以查看活跃线程数与连接数了,但有些情况下,会丧失一些细节,如下:

  1. top中的线程名会截断,如果不同线程池的线程名前16字符一样,则在top中无法区分。
  2. ss中是通过端口来区分线程池的,但http服务的端口号基本都是80或443,所以不同域名的http服务的连接池无法区分。

若需要分辩这些细节,还是要深入到jvm里面来,而arthas就是一个不错的工具,它的vmtool命令能够获取指定类型的Java对象,并从Java对象中获取信息。

以springboot为例,获取内置tomcat线程池的活跃情况,如下:

# --action getInstances:表示获取对象实例
# --classLoaderClass:指定类加载器
# --className:指定要获取哪个类的实例
# --express:指定ognl表达式,用来从对象上获取信息
[arthas@1]$ vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.apache.tomcat.util.threads.ThreadPoolExecutor  --express 'instances.{ #{"ActiveCount":getActiveCount(),"LargestPoolSize":getLargestPoolSize(),"CorePoolSize":getCorePoolSize(),"MaximumPoolSize":getMaximumPoolSize(),"QueueSize":getQueue().size(),"ThreadName":getThreadFactory().namePrefix }}' -x 2

image_2023-03-04_20230304155857
上面其实就是通过vmtool工具,获取到了tomcat的线程池对象,然后调用线程池的getActiveCount()等方法,获取到了活跃线程数🙄

要获取连接池的活跃情况,也一并呈上吧,如下:

# 获取druid连接池的使用情况
[arthas@1]$ vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className com.alibaba.druid.pool.DruidDataSource  --express 'instances.{ #{"url":#this.getUrl().split("\\?")[0], "username":#this.getUsername(),"PoolingCount":#this.getPoolingCount(),"ActiveCount":#this.getActiveCount(),"MaxActive":#this.getMaxActive(),"WaitThreadCount":#this.getWaitThreadCount(),"MaxWaitThreadCount":#this.getMaxWaitThreadCount()} }' -x 2

# 获取httpclient连接池的使用情况
[arthas@1]$ vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.apache.http.impl.conn.PoolingHttpClientConnectionManager --express 'instances.{ #pool=#this.pool.routeToPool.values() }' -x2

可以看到,arthas真的很方便实用,对于Java Boy来说,值得好好研究研究👍👍👍

作者:打码日记

出处:https://www.cnblogs.com/codelogs/p/17178675.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

与[转帖] 在Linux上查看活跃线程数与连接数相似的内容:

[转帖] 在Linux上查看活跃线程数与连接数

https://www.cnblogs.com/codelogs/p/17178675.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。 简介# 现如今,有两种常见的软件资源几乎成了Java后端程序的标配,即线程池与连接池,但这些池化资源非常的重要,一

[转帖]Docker容器日志查看与清理(亲测有效)

1. 问题 docker容器日志导致主机磁盘空间满了。docker logs -f container_name噼里啪啦一大堆,很占用空间,不用的日志可以清理掉了。 2. 解决方法 2.1 找出Docker容器日志 在linux上,容器日志一般存放在/var/lib/docker/container

[转帖]如何在 60秒内优化提升 Linux 性能?只有 2% 的人知道,还不快来学习~

https://bbs.huaweicloud.com/blogs/379243 【摘要】 如何在 60秒内优化提升 Linux 性能?只有 2% 的人知道 当你发现 Linux 服务器上的系统性能问题,在最开始的 1 分钟时间里,你会查看哪些系统指标呢? Netflix 在 AWS 上有着大规模的

[转帖]使用Linux命令快速查看某一行

原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介# 当年,我还是Linux菜鸟的时候,就在简历上写着精通Linux命令了,而当面试官问我“如何快速查看某个文件的第200行,仅这一行”时,我的心里是懵逼的。 当时面试官心里估计在窃喜,从我敷衍的回答中,他应该已经完全

[转帖]《Linux性能优化实战》笔记(三)—— CPU 上下文切换(下)

上篇介绍了三种CPU 上下文切换以及它们可能造成的问题和原因,这一篇来看看在系统中如何发现CPU 上下文切换问题。 一、 查看上下文切换情况 主要使用两个命令:vmstat以及之前用过的pidstat。 1. vmstat # 每隔5秒输出1组数据vmstat 5 procs memory swap

[转帖]50个应知必会的Linux常识和操作

1.存放用户账号的文件在哪里? /etc/passwd 1 2.如何删除一个非空的目录? rm -rf 目录名 1 3.查看当前的工作目录用什么命令? pwd 1 4.创建一个文件夹用什么命令? mkdir 1 5.哪个Linux命令可以一次显示一页内容?上一页和下一页使用什么命令? more Sp

[转帖]Linux 调优篇:虚拟化调优(hugepage 大页内存)* 叁

一. 大页(HugePages)概念 Hugepage的引入二. hugepages相关概念三.Regular Pages 与 HugePages a、Regular Pages b、Huge Pages四. hugepage 优点五.调优方法 5.1 在Host侧查看各个numa节点上的大页分配情

【转帖】Linux 调优篇:虚拟化调优(hugepage 大页内存)* 叁

一. 大页(HugePages)概念 Hugepage的引入二. hugepages相关概念三.Regular Pages 与 HugePages a、Regular Pages b、Huge Pages四. hugepage 优点五.调优方法 5.1 在Host侧查看各个numa节点上的大页分配情

【转帖】【奇淫技巧】Linux | 查找文件,无所遁形

theme: channing-cyan 本文正在参与 “走过Linux 三十年”话题征文活动 在Linux系统上,最常见的操作莫过于处理文本。常见文件操作陈列、查找、排序、格式转换、数据流处理等等。这篇文章着眼于文件查找,分析locate和find命令的使用方法,和运用原理以及缺陷不足。 一、导读

[转帖]linux 上进程被随机kill掉,如何监测和查询;谁杀了我的进程;Who sends a SIGKILL to my process mysteriously on ubuntu server

https://www.cnblogs.com/xuyaowen/p/linux-audit.html 今天跑实验,发现进程被随机kill。咨询了服务器上的其他同学,他们说之前也发生过,一直存在。看来可能有可能不是我自己程序的原因,只能自己动手解决了。 在 Who sends a SIGKILL t