作者:闫虎青DBLE开源项目负责人,负责分布式数据库中间件研发;持续专注于数据库技术,始终在第一线从事开发工作;数据复制,读写分离,分库分表的深入理解和实践。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得使用,转载请联系小编并注明出处。据说有一天,dble团队的测试小伙伴需要了解调优dble的原理和方法来做性能调优,于是丢给他一份文档让他研究:https://actiontech.github.io/……测试同学一脸不屑的看了文档,然后问我,图中这个命令是干什么用的?使用原生的Linuxtop命令还不够吗?你为此做什么?表达的机会来了,于是我耐心地告诉他,虽然原生的top命令对cpu的统计比较准确,但是对Java线程并不友好。线程名全部显示java,与应用实际线程名不一致。jstack去查,就这样,边说边开始demo。首先,top命令提供了正在运行的动态实时视图。它可以显示系统摘要信息和当前由Linux内核管理的进程或线程的列表。显示信息的类型和顺序是可配置和持久的。..(“切入正题,不要凑字数”,测试同学打断了口若悬河的我)。好了,说说重点吧。默认情况下,top显示单个进程中所有线程的指标总和。我们可以使用参数-H来指定显示线程的信息。另外,参数-p还可以指定具体的进程id。执行看看:top-H-p`pidofjava`结果大概是这样的:这个结果有什么用呢?得通过jstack命令打印一个stack(当然如果是线上环境可能要承担一定的风险)jstack-l`pidofjava`>/tmp/dble_jstack.log有了这两个结果,我们就可以看出某某thread在应用程序中做一个对应的线程号。具体怎么做呢?比如我们取一个线程号如10849,将其转换成十六进制数printf"%x\n"108492a61,然后在jstack结果中查找线程名。猫/tmp/dble_jstack.log|grep"nid=0x2a61""BusinessExecutor0"#23daemonprio=5os_prio=0tid=0x00007f95dc620800nid=0x2a61waitingoncondition[0x00007f96281f6000]当然,如果只需要线程名,这就够了,两行命令即可也可以拼接在一起。如果需要更多的上下文信息,可以查看grep手册找到-A、-B等相应的参数,甚至打开文件也能找到。我也跟他说,在实际运维工作中,如果发现java进程的CPU飙升,如何排查?也是同样的方法,先通过top命令找到高CPU的线程,然后通过jstack知道线程在做什么,尝试解决高CPU的问题,根据我的经验,多半是因为的gc问题,也遇到了nio的epollbug。测试同学在后半段静静的听了我的介绍和演示,在自己的Ubuntu终端输入了同样的一行命令:top-H-p`pidofjava`然后指着结果问我:有没有问题?线程名称?这。..大写的尴尬打脸场面,脑子里满是问号,只好乖乖认了,去研究为什么上级在他的机子上比我的机子还听话。经过几个小时和几个晚上的调查(但事实并非如此),我终于弄明白了为什么线程名称没有显示出来。原来早在2011年就有人提出问题(参见JDK-7102541),在JDK-8179011中给出了更简单的描述。早在2019年就修复了,openjdk向后移植到了8u222版本,也就是说openjdk版本已经修复了这个问题,但是我写这篇文章的时候,Oraclejdk8u301还是没有修复这个问题。这样读者就知道如何选择jdk了。既然修复了bug,就忍不住想看看具体是怎么实现的。这里主要关注Linux平台的实现。这里还有一件有趣的事。我们其实可以看到这是SAP的一个大牛在2014年实现的一个功能。让我们详细看看代码。首先在线程实现层面设置线程的名称:然后是set_native_thread_name方法的具体实现。Linux平台上的代码如下:可以看到,这里截取了线程名的前15个字符。然后调用Linux::_pthread_setname_np方法。看这个方法做了什么:可以看出,这其实是通过dlsym调用操作系统的pthread_setname_np方法。至此,调查结束。我们总结了以下几点:如果使用Oraclejdk8或者更早的jdk,就得用jstack或者其他的方法来对应线程号和逻辑线程名。如果你用的是openjdk8,建议升级到222,这样可以通过top命令直接看到线程的名字,加快诊断速度。建议应用在设置线程名称时,尽量在15个字符以内表达出独特的含义,便于观察和分析。当然这个dble做得不好,后面会调整修改。当然社区还有一些其他的工具,比如阿里的Arthas应该也可以实现线程id和name对应的功能,但是引入第三方总是一件比较麻烦的事情,原生的比较多香。参考文档:http://hg.openjdk.java.net/jd...https://bugs.openjdk.java.net...https://bugs.openjdk.java.net...https:///bugs.openjdk.java.net...https://man7.org/linux/man-pa...https://man7.org/linux/man-pa...
