Linux下高cpu解决方案(转载)

昨天搞定了一个十万火急的issue,客户抱怨产品升级后系统会变慢和CPU使用率相当高,客户脾气很大,声称不尽快解决这个问题就退货,弄得我们 R&D压力很大,解决这个issue的任务分给了我,客户是南非的一个公司,由于时差问题,我只好在家远程解决问题,晚上8点半用 gotomeeting远程到客户电脑查看我们的系统,折腾了四个多小时,终于在凌晨时reproduce了这个high CPU,赶紧抓Log,用wireshark抓包,用gcore,gstack,strace和top保存了系统的相关输出。在第2天分析了这些文件后, 找到了产品的bug,代码的作者分配了10K的缓冲区,并想当然认为10K足以够用,当然99%的情况下是够用的,但是在这1%的情况下出现了问题,缓冲 区不幸被写满了,然后程序进入了死循环,导致high CPU。找到了问题了,fix就很容易了,客户的脾气也缓和了,fix很快就可以deliver给客户。反思解决问题的过程,觉得这个分析过程具有可复用 性,值得总结一下。

1.用top命令查看哪个进程占用CPU高
gateway网关进程14094占用CPU高达891%,这个数值是进程内各个线程占用CPU的累加值。

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14094 root 15 0 315m 10m 7308 S 891% 2.2 1:49.01 gateway
20642 root 17 0 17784 4148 2220 S 0.5 0.8 2:39.96 microdasys
1679 root 18 0 10984 1856 1556 R 0.3 0.4 0:22.21 sshd
22563 root 18 0 2424 1060 800 R 0.3 0.2 0:00.03 top
1 root 18 0 2156 492 460 S 0.0 0.1 0:01.59 init

2.用top -H -p pid命令查看进程内各个线程占用的CPU百分比

#top -H -p 14094
top中可以看到有107个线程,但是下面9个线程占用CPU很高,下面以线程14086为主,分析其为何high CPU

PID USER PR NI VIRT RES SHR S %CPU MEM TIME+ COMMAND
14086 root 25 0 922m 914m 538m R 101 10.0 21:35.46 gateway
14087 root 25 0 922m 914m 538m R 101 10.0 10:50.22 gateway
14081 root 25 0 922m 914m 538m S 99 10.0 8:57.36 gateway
14082 root 25 0 922m 914m 538m R 99 10.0 11:51.92 gateway
14089 root 25 0 922m 914m 538m R 99 10.0 21:21.77 gateway
14092 root 25 0 922m 914m 538m R 99 10.0 19:55.47 gateway
14094 root 25 0 922m 914m 538m R 99 10.0 21:02.21 gateway
14083 root 25 0 922m 914m 538m R 97 10.0 21:32.39 gateway
14088 root 25 0 922m 914m 538m R 97 10.0 11:23.12 gateway

3.使用gstack命令查看进程中各线程的函数调用栈
#gstack 14094 > gstack.log
在gstack.log中查找线程ID14086,由于函数栈会暴露函数细节,因此只显示了两个函数桢,线程ID14086对应线程号是37

Thread 37 (Thread 0x4696ab90 (LWP 14086)):
#0 0x40000410 in __kernel_vsyscall ()
#1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6

4.使用gcore命令转存进程映像及内存上下文

#gcore 14094
该命令生成core文件core.14094

5。用strace命令查看系统调用和花费的时间
#strace -T -r -c -p 14094

-c参数显示统计信息,去掉此参数可以查看每个系统调用话费的时间及返回值。

% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------------------
99.99 22.683879 3385 6702 poll
0.00 0.001132 0 6702 gettimeofday
0.00 0.000127 1 208 208 accept
0.00 0.000022 22 1 read
0.00 0.000000 0 1 write
0.00 0.000000 0 1 close
0.00 0.000000 0 14 time
0.00 0.000000 0 2 stat64
0.00 0.000000 0 4 clock_gettime
0.00 0.000000 0 7 send
0.00 0.000000 0 10 10 recvfrom
------ ----------- ----------- --------- --------- ------------------------------
100.00 22.685160 13652 218 total

6.用gdb调试core文件,并线程切换到37号线程
gcore和实际的core dump时产生的core文件几乎一样,只是不能用gdb进行某些动态调试

(gdb) gdb gateway core.14094
(gdb) thread 37
[Switching to thread 37 (Thread 0x4696ab90 (LWP 14086))]#0 0x40000410 in __kernel_vsyscall ()
(gdb) where
#0 0x40000410 in __kernel_vsyscall ()
#1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6

可以根据详细的函数栈进行gdb调试,打印一些变量值,并结合源代码分析为何会poll调用占用很高的CPU。
因为代码涉及到公司产权,顾不在此做详细分析,需要明白的是分析的流程和使用的命令。

流程为:进程ID->线程ID->线程函数调用栈->函数耗时和调用统计->源代码分析

时间: 2024-08-15 04:04:36

Linux下高cpu解决方案(转载)的相关文章

Linux下高cpu解决方案

昨天搞定了一个十万火急的issue,客户抱怨产品升级后系统会变慢和CPU使用率相当高,客户脾气很大,声称不尽快解决这个问题就退货,弄得我们 R&D压力很大,解决这个issue的任务分给了我,客户是南非的一个公司,由于时差问题,我只好在家远程解决问题,晚上8点半用 gotomeeting远程到客户电脑查看我们的系统,折腾了四个多小时,终于在凌晨时reproduce了这个high CPU,赶紧抓Log,用wireshark抓包,用gcore,gstack,strace和top保存了系统的相关输出.在

Linux下调节CPU使用的几种方法

一,使用taskset充分利用多核cpu,让cpu的使用率均衡到每个cpu上 #taskset-p,    设定一个已存在的pid,而不是重新开启一个新任务-c,    指定一个处理,可以指定多个,以逗号分隔,也可指定范围,如:2,4,5,6-8. 1,切换某个进程到指定的cpu上taskset -cp 3 13290 2,让某程序运行在指定的cpu上taskset -c 1,2,4-7 tar jcf test.tar.gz test 需要注意的是,taskset -cp 3 13290在设定

Linux下高并发socket最大连接数所受的各种限制(详解)

1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄).可使用ulimit命令查看系统允许当前用户进程打开的文件数限制: [[email protected] ~]$ ulimit -n1024 这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中

Linux下高并发socket链接数测试

一.如何增大service进程的max open files ulimit -n 只能改小max open files,不能改大.需要按照以下步骤: 修改/etc/security/limits.conf文件,将"soft nofile 655360"和"hard nofile 655360"这两行的655360改成期望的值 退出,重新ssh该机器(否则无效) 修改对service的启动脚本,增加"ulimit -n 950000",其中9500

Linux下查看CPU信息

linux下查看CPU的信息主要通过查看/proc/cpuinfo这个文件. 一.针对/proc/cpuinfo文件,我们需要查看processor,physical id,siblings,core id,cpu cores这几个字段. 1.拥有相同physical id的所有逻辑处理器共享同一个物理插座.每个physical id 代表一个唯一的物理封装,即一颗CPU. 2.Siblings表示位于一个物理封装的CPU上逻辑CPU的个数. 3.每个core id 均代表一个唯一的处理器内核,

Linux下获得CPU的信息

1.查看物理cpu个数 cat /proc/cupinfo |grep 'physical id'|sort|uniq|wc -l 2.查看一个cpu的物理核数 cat /proc/cupinfo |grep 'core id'|sort|uniq -c|wc -l 或 cat /proc/cupinfo |grep 'cpu cores'|uniq|awk -F ":" '{print $2}' 3.查看一个cpu的逻辑核数 cat /proc/cupinfo |grep 'sibl

linux下高并发网络应用注意事项

本文转自:http://www.blogjava.net/bacoo/archive/2012/06/11/380500.html linux下高并发网络应用注意事项 vi /etc/sysctl.conf,加入以下内容:net.ipv4.tcp_tw_reuse=1 #表示开启重用.允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭net.ipv4.tcp_tw_recycle=1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表

Linux下Setuid命令! 转载

Linux下Setuid命令! 转载 在Linux系统中每个普通用户都可以更改自己的密码,这是合理的设置. 问题是:用户的信息保存在文件/etc/passwd中,用户的密码保存在文件/etc/shadow中,也就是说用户更改自己密码时是修改了/etc/shadow文件中的加密密码,但是, -rw-r--r-- 1 root root 1787 Oct 27  2009 /etc/passwd -r-------- 1 root root 1187 Oct 27  2009 /etc/shadow

Linux下查询CPU 缓存的工具

在Linux下能够使用例如以下工具查询CPU缓存: 方式1: $ lscpu L1d cache: 32K <span style="white-space:pre"> </span>(一级数据缓存) L1i cache: 32K <span style="white-space:pre"> </span><span style="font-family: Arial, Helvetica, sans-