首先查看nginx的error日志,无异常打印。

cpu占用如下图所示:

top - 10:05:40 up 233 days, 16:28, 4 users, load average: 25.53, 25.39, 21.62
Tasks: 836 total, 20 running, 816 sleeping, 0 stopped, 0 zombie
Cpu(s): 51.8%us, 4.1%sy, 0.0%ni, 31.0%id, 6.1%wa, 0.0%hi, 6.9%si, 0.0%st
Mem: 257940M total, 254533M used, 3407M free, 6481M buffers
Swap: 0M total, 0M used, 0M free, 190273M cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16645 root 20 0 15.6g 7.2g 7.1g R 99 2.9 19888:06 nginx
16643 root 20 0 15.6g 7.2g 7.1g R 98 2.9 19917:31 nginx
16641 root 20 0 15.6g 7.2g 7.1g R 98 2.9 19547:57 nginx
16661 root 20 0 15.6g 7.2g 7.1g R 97 2.9 19957:15 nginx
16659 root 20 0 15.6g 7.2g 7.1g R 97 2.9 20032:33 nginx
16637 root 20 0 15.6g 7.2g 7.1g R 96 2.9 21085:44 nginx
16640 root 20 0 15.6g 7.2g 7.1g R 96 2.9 16897:32 nginx
16644 root 20 0 15.6g 7.2g 7.1g R 96 2.9 19860:42 nginx
16638 root 20 0 15.6g 7.2g 7.1g R 96 2.9 16362:11 nginx
16648 root 20 0 15.6g 7.2g 7.1g R 96 2.9 16627:30 nginx
16669 root 20 0 15.6g 7.2g 7.1g R 96 2.9 17290:48 nginx
16653 root 20 0 15.6g 7.2g 7.1g R 96 2.9 17093:40 nginx
16656 root 20 0 15.6g 7.2g 7.1g R 96 2.9 19544:29 nginx

nginx的cpu占用很高,且处于用户态占用。单独查看16645进程的cpu占用如下:

top -H -p 16645

top - 10:06:09 up 233 days, 16:28, 4 users, load average: 26.95, 25.73, 21.83
Tasks: 68 total, 1 running, 67 sleeping, 0 stopped, 0 zombie
Cpu(s): 8.0%us, 5.5%sy, 0.0%ni, 63.8%id, 13.0%wa, 0.0%hi, 9.7%si, 0.0%st
Mem: 257940M total, 254387M used, 3552M free, 6481M buffers
Swap: 0M total, 0M used, 0M free, 190106M cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16645 root 20 0 15.6g 7.2g 7.1g R 94 2.9 15689:54 nginx
18749 root 20 0 15.6g 7.2g 7.1g S 0 2.9 42:31.63 nginx
18751 root 20 0 15.6g 7.2g 7.1g S 0 2.9 63:29.10 nginx
18753 root 20 0 15.6g 7.2g 7.1g S 0 2.9 64:42.03 nginx
18755 root 20 0 15.6g 7.2g 7.1g S 0 2.9 65:18.44 nginx
18757 root 20 0 15.6g 7.2g 7.1g S 0 2.9 65:02.60 nginx

还好,是单独一个线程cpu高,以前遇到复杂的,是cpu各个线程之间跳着高。

想用perf看一下热点函数:

perf top -p 16645
If 'perf' is not a typo you can run the following command to lookup the package that contains the binary:
command-not-found perf
-bash: perf: command not found

发现命令没装,由于是线上环境,出现一次也不容易,所以只能attch上去手工采样,看这个线程在忙什么。

由于是多线程的进程,所以要确定线程号,然后看堆栈,info thr 确定线程号之后,切换到对应的堆栈,然后bt查看堆栈。

部分堆栈如下:

(gdb) info thr
Id Target Id Frame
68 Thread 0x7f4ef02e2700 (LWP 17129) "nginx" 0x00007f5154c1666c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
67 Thread 0x7f4eefae1700 (LWP 17132) "nginx" 0x00007f5154c1666c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0

......................//省略中间部分

2 Thread 0x7f4d71635700 (LWP 19135) "nginx" 0x00007f5154015b1d in nanosleep () from /lib64/libc.so.6
* 1 Thread 0x7f5155419720 (LWP 16645) "nginx" 0x00007f51547b4ac0 in ?? () from /usr/local/lib/libluajit-5.1.so.2

(gdb) thr 1
[Switching to thread 1 (Thread 0x7f5155419720 (LWP 16645))]

对应的堆栈如下:

(gdb) bt
#0 0x00007f51547b47e7 in ?? () from /usr/local/lib/libluajit-5.1.so.2
#1 0x00007f51547b4865 in ?? () from /usr/local/lib/libluajit-5.1.so.2
#2 0x00007f51547b4af4 in ?? () from /usr/local/lib/libluajit-5.1.so.2
#3 0x00007f51547b4c17 in ?? () from /usr/local/lib/libluajit-5.1.so.2
#4 0x00007f51547b489f in ?? () from /usr/local/lib/libluajit-5.1.so.2
#5 0x00007f51547b54aa in ?? () from /usr/local/lib/libluajit-5.1.so.2
#6 0x00007f515476c4eb in ?? () from /usr/local/lib/libluajit-5.1.so.2
#7 0x00000000005400ab in ngx_http_lua_run_thread (L=0x417ac378, r=0xc26fd0, ctx=0xed1800, nrets=1) at ./required/lua-nginx-module-0.9.19/src/ngx_http_lua_util.c:1015
#8 0x000000000052636a in ngx_http_lua_subrequest_resume (r=0xc26fd0) at ./required/lua-nginx-module-0.9.19/src/ngx_http_lua_subrequest.c:1595
#9 0x0000000000545b0f in ngx_http_lua_content_wev_handler (r=0xc26fd0) at ./required/lua-nginx-module-0.9.19/src/ngx_http_lua_contentby.c:131

由于用户态采样毕竟频率过低,最好要进行多次采样确定地址,连续多次采样,确认堆栈不变。

ngx_http_lua_run_thread 是nginx调用的lua第三方模块,根据堆栈r=0xc26fd0,我们可以获取到如下信息:

(gdb) p ((ngx_http_request_t*)0xc1cab0).request_line.data
$22 = (
u_char *) 0x1a4b5e0 "GET /001/2/ch00000090990000001073/2560000.m3u8?"...

很可惜,url打印不全,这个是由于默认情况下,gdb会根据性能要求,打印一定长度的字符串,修改下gdb的字符串打印配置如下:

(gdb) set print element 0           -----------这个0就是全部打印,如果是200,就默认打印200个字符,前提是没有遇到\0

比如设置为1,则打印是如下:

(gdb) set print element 1
(gdb) p ((ngx_http_request_t*)0xc1cab0).request_line.data
$28 = (u_char *) 0x1a4b5e0 "G"...

重新设置为0,打印的数据涉及到保密,就不展示了,反正获取到了url,接下来就轻松了,curl请求该url,cpu立刻飙升至100,完美复现。

后面的分析就不重要了,gdb跟一把ok。收工。

nginx cpu高排查的更多相关文章

  1. 服务器CPU使用率过高排查与解决思路

    发现服务器的cpu使用率特别高 排查思路: -使用top或者mpstat查看cpu的使用情况# mpstat -P ALL 2 1Linux 2.6.32-358.el6.x86_64 (linux— ...

  2. Java进程CPU使用率高排查

    Java进程CPU使用率高排查 生产java应用,CPU使用率一直很高,经常达到100%,通过以下步骤完美解决,分享一下.1.jps 获取Java进程的PID.2.jstack pid >> ...

  3. CPU高问题排查

    双11大战开始了,这几天公司系统压测,CPU各种报警,于是找了篇关于CPU高问题排查的文章. 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎 ...

  4. 一次线上CPU高的问题排查实践

    一次线上CPU高的问题排查实践 前言 近期某一天上班一开电脑,就收到了运维警报,有两台服务CPU负载很高,同时收到一线同事反馈 系统访问速度非常慢,几乎无响应. 一个美好的早晨,最怕什么就来什么.只好 ...

  5. 再一次生产 CPU 高负载排查实践

    前言 前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨. 其实早在去年我也处理过类似的问题,并记录下来:<一次生产 CPU 1 ...

  6. 记一次排查CPU高的问题

    背景 将log4j.xml的日志级别从error调整为info后,进行压测发现CPU占用很高达到了90%多(之前也就是50%,60%的样子). 问题排查 排查思路:  看进程中的线程到底执行的是什么, ...

  7. NGINX 502错误排查(转)

    一.NGINX 502错误排查 NGINX 502 Bad Gateway错误是FastCGI有问题,造成NGINX 502错误的可能性比较多.将网上找到的一些和502 Bad Gateway错误有关 ...

  8. nginx php-fpm 高并发优化

    PHP-php-fpm配置优化 前言: 1.少安装PHP模块, 费内存 2.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号)(我是修改/etc/rc.local,加入ulimit ...

  9. Nginx突破高并发的性能优化 - 运维笔记

    在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题.今天这里简单梳理下nginx性能优化的配置(仅仅依据本人的实战经验而述,如有不妥,敬请指出~) 一.这里 ...

随机推荐

  1. mysql获得自增的下条id的值

    需求: 当数据表中存在一个字段需要该条数据中自增长的id值 实现方法:(1)代码中先插入该条数据后,再次修改数据 (2)在数据库中使用触发器完成 具体实现:实现方法中的第一种方法就不在此实现,以下便是 ...

  2. Codeforces_776B: Sherlock and his girlfriend(素数筛)

    题目链接 题意:对2~n+1染色,一个数不能与其素因子同色. 故而只需两种颜色即可,素数染1,合数染2便可满足条件 #include<bits/stdc++.h> using namesp ...

  3. 学会用requirejs,5分钟足矣

    学会用requirejs,5分钟足矣 据说公司的项目较多的用到requirejs管理依赖,所以大熊同学挤出了5分钟休息时间学习了一下,现在分享一下.如果你想了解requirejs的实现原理,请绕道!如 ...

  4. Jenkins2 插件 Pipeline+BlueOcean 实现持续交付的初次演练

    需要完成的目标 使用Pipeline完成项目的checkout,package.deploy.restart 提取出公有部分封装为公有JOB 实现pipeline对其他JOB的调用和逻辑的判断 实现任 ...

  5. 1.Why Apache Spark?

    Why Apache Spark? 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark ...

  6. git相关的学习资料

    1, 一个比较详细的git使用说明: http://blog.jobbole.com/78960/

  7. phantomjs submit click

    phantomjs 一般提交时都会用submit,前提条件就是网页中有form表单: 在网页中无form表单的情况下,用submit()会报错:selenium.common.exceptions.N ...

  8. Tornado-StaticFileHandler参考

    StaticFileHandler ====== tornado.web.StaticFileHandler 源代码中的解释 class StaticFileHandler(RequestHandle ...

  9. mybatis 详解(三)------入门实例(基于注解)

    1.创建MySQL数据库:mybatisDemo和表:user 详情参考:mybatis 详解(二)------入门实例(基于XML) 一致 2.建立一个Java工程,并导入相应的jar包,具体目录如 ...

  10. vue的一些坑(第一天)

    1:刚开始在创建项目的时候一直出现vue不是内部或外部命令 关于这个的解决方案网上给出的很多的解决方案是配置环境,这个我就不在赘述了: 但是我觉得那样太麻烦,就没用,只是重新 npm i vue-cl ...