Linux进程多导致CPU卡死的问题

本文详细记录了服务器CPU负载过高和邮件系统空间不足导致的问题,包括日志分析、进程检查、空间清理以及系统优化的过程。通过top命令监控进程、使用lsof查看文件打开情况、清除历史监控日志、修改cron.d中的sysstat配置等步骤,最终解决了服务器性能问题并释放了磁盘空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.youkuaiyun.com/guoyjoe/article/details/49924557

一、邮箱收到一堆监控,报警内空大致如下,很明显是CPU不够用了,IO也有点问题:主机: bwebser2__10.253.5.198 时间: 2015.11.15 15:25:17状态: PROBLEM 级别: Warning报警原因: Processor load is too high on bwebser2内容: Processor load (1 min average per core):value=52.53原始事件ID: 30605主机: bwebser2__10.253.5.198时间: 2015.11.18 15:42:23 状态: PROBLEM级别: Warning 报警原因: Disk I/O is overloaded on bwebser2 内容: CPU iowait time:value=68.7 %原始事件ID: 30812

二、用top查看进程,发现有近2000个进程

[root@bwebser2 ~]# top
top - 10:00:32 up 184 days, 19:55,  2 users,  load average: 49.39, 52.06, 53.04
Tasks: 1826 total,   1 running, 1825 sleeping,   0 stopped,   0 zombie
Cpu(s): 22.5%us,  3.8%sy,  0.0%ni, 31.7%id, 41.3%wa,  0.7%hi,  0.0%si,  0.0%st
Mem:   8058056k total,  7631808k used,   426248k free,   718780k buffers
Swap:        0k total,        0k used,        0k free,   358720k cached


三、猜测可能和sendmail有关,查maillog日志,一直报警:No space left on device

[root@bwebser2 ~]# tail -f  /var/log/maillog     
Nov 19 10:12:15 bwebser2 postfix/postdrop[19470]: warning: mail_queue_enter: create file maildrop/878633.19470: No space left on device
Nov 19 10:12:15 bwebser2 postfix/postdrop[27287]: warning: mail_queue_enter: create file maildrop/900082.27287: No space left on device
Nov 19 10:12:15 bwebser2 postfix/postdrop[12347]: warning: mail_queue_enter: create file maildrop/919377.12347: No space left on device
Nov 19 10:12:15 bwebser2 postfix/postdrop[21222]: warning: mail_queue_enter: create file maildrop/937001.21222: No space left on device
Nov 19 10:12:16 bwebser2 postfix/postdrop[25028]: warning: mail_queue_enter: create file maildrop/956095.25028: No space left on device
Nov 19 10:12:16 bwebser2 postfix/postdrop[28123]: warning: mail_queue_enter: create file maildrop/980022.28123: No space left on device
Nov 19 10:12:16 bwebser2 postfix/postdrop[26680]: warning: mail_queue_enter: create file maildrop/999360.26680: No space left on device


四、用lsof确定sendmail、postdrop进程数量,进程数达到2000多个,为什么有这么多呢?

[root@bwebser2 ~]# lsof |grep sendmail |wc -l
24682
[root@bwebser2 ~]# lsof |grep postdrop  |wc -l
24108



五、查看文件索引节点inode,发现空间满了:

[root@bwebser2 log]# df -i
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
/dev/xvda1      1310720 1310720        0  100% /
tmpfs           1007257       1  1007256    1% /dev/shm
/dev/xvdb1     13107200    6142 13101058    1% /u01

用df -Th命令:
root@cwebser3 statistics]# df -Th
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/xvda1     ext4    20G  4.1G   15G  22% /
tmpfs          tmpfs  3.9G     0  3.9G   0% /dev/shm
/dev/xvdb1     ext3   197G   18G  170G  10% /u01


六、通过清除zookeeper监控日志把腾出根的空间

cd /home/zookeeper/monitor 
[root@bwebser2 monitor]# ll
total 8
drwxrwxr-x 163 zookeeper zookeeper 4096 Nov 12 00:16 charts
drwxrwxr-x 167 zookeeper zookeeper 4096 Nov 18 17:31 statistics
[root@bwebser2 monitor]# cd charts
rm -rf *
[root@bwebser2 monitor]# cd ../statistics/
[root@bwebser2 statistics]# rm -rf 201506*
[root@bwebser2 statistics]# rm -rf 201507*
[root@bwebser2 statistics]# rm -rf 201508*
[root@bwebser2 statistics]# rm -rf 201509*
[root@bwebser2 statistics]# rm -rf 201510*


七、杀死所有sendmail和postdrop进程后

[root@bwebser2 ~]#ps -ef|grep sendmail | grep -v grep | awk  '{print "kill -9 " $2}' |sh
[root@bwebser2 ~]#ps -ef|grep postdrop | grep -v grep | awk  '{print "kill -9 " $2}' |sh



八、lsof查看,进程数为0

[root@bwebser2 ~]# lsof |grep sendmail |wc -l
0
[root@bwebser2 ~]# lsof |grep postdrop  |wc -l
0


九、被忽略的/etc/cron.d下的sysstat,修改sysstat,操作如下:

[root@bwebser2 cron.d]#cd /etc/cron.d/
[root@bwebser2 cron.d]# ll
total 12
-rw-r--r--. 1 root root 113 Nov 23  2013 0hourly
-rw-r--r--. 1 root root 108 Apr  7  2014 raid-check
-rw-r--r--. 1 root root 235 Nov 23  2013 sysstat
 
vi sysstat添加&>/dev/null
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib/sa/sa1 1 1 &>/dev/null
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib/sa/sa2 -A &>/dev/null  


十、再次用top命令查看进程只有100多个,监控报警消失,问题搞定!

[root@bwebser2 cron.d]# service sendmail restart
sendmail: unrecognized service
[root@cwebser3 cron.d]# top
top - 10:43:12 up 184 days, 20:37,  2 users,  load average: 1.03, 1.54, 14.15
Tasks: 105 total,   1 running, 104 sleeping,   0 stopped,   0 zombie
Cpu(s): 43.4%us,  1.3%sy,  0.0%ni, 47.9%id,  7.0%wa,  0.3%hi,  0.0%si,  0.0%st
Mem:   8058056k total,  6762996k used,  1295060k free,  1422060k buffers
Swap:        0k total,        0k used,        0k free,   381392k cached




<think>嗯,用户问的是在提升进程调度优先级后主进程卡死问题。首先,我得回忆一下进程调度优先级的相关知识。Linux中的优先级通常是通过nice值或实时优先级(rtprio)来调整的。nice值范围是-20到19,数值越小优先级越高,而实时优先级范围是1到99,数值越大优先级越高,但实时进程可能会抢占大部分系统资源。 用户提到提升优先级后主进程卡死,可能的原因有几个方向。首先,优先级设置过高导致其他关键进程无法执行,比如内核线程或硬件交互进程被饿死,进而系统无法正常调度。其次,实时优先级设置不当可能让进程占用CPU不放,触发内核的watchdog机制将其杀死。还有可能进程进入死锁或忙等待状态,尤其是高优先级下更难被抢占,导致卡死。 接下来需要分析具体的情况。用户是用nice命令还是rtprio?如果是实时优先级,比如使用SCHED_FIFO策略,并且优先级设得很高,比如99,那这个进程可能会一直占用CPU,除非它主动让出。这时候,如果进程里有无限循环且没有休眠机制,就会导致系统无法调度其他进程,包括必要的系统进程,从而卡死。 另外,资源竞争的问题。高优先级进程如果频繁申请资源,可能导致低优先级进程无法释放锁,从而形成死锁。或者,进程可能因为优先级提升后,竞争不到某些资源而陷入等待状态,但同时又持有其他资源,导致死锁。 解决方法的话,可能需要检查优先级设置是否合理,尤其是避免使用实时优先级过高,除非必要。对于需要长时间运行的进程,应该加入适当的休眠或调度点,比如调用sched_yield()或nanosleep(),让出CPU。另外,检查代码中的资源管理,避免死锁,使用超时机制等。 还有系统配置方面,比如RLIMIT_RTTIME的限制,防止进程超过最大运行时间被杀死。使用工具如strace或gdb附加到进程,查看卡死时的状态,是否有阻塞的系统调用或死锁现象。监控系统日志,看是否有内核报错或进程被kill的记录。 总结起来,需要从优先级设置、进程行为、资源竞争、系统配置等个方面排查,逐步调整和验证,找到导致卡死的具体原因。</think>### 问题分析:提升进程调度优先级后主进程卡死 #### 1. 优先级机制背景 在Linux系统中,进程调度优先级分为两种类型: - **普通优先级**:通过`nice`值调整(范围-20到19,值越小优先级越高) - **实时优先级**:通过`rtprio`调整(范围1到99,值越大优先级越高,需`SCHED_FIFO`或`SCHED_RR`策略) #### 2. 常见卡死原因 以下情况可能导致进程卡死: **(1) 优先级设置过高导致资源饥饿** - 若将进程设为最高实时优先级(如99),它可能独占CPU导致关键系统进程(如内核线程、硬件交互进程)无法执行。 - 示例代码风险: ```c struct sched_param param = { .sched_priority = 99 }; sched_setscheduler(0, SCHED_FIFO, &param); // 高风险操作 ``` **(2) 触发内核保护机制** - Linux内核的`watchdog`会检测CPU饥饿状态,可能直接杀死占用CPU超过阈值的进程: ```bash dmesg | grep "sched: RT throttling activated" # 查看相关日志 ``` **(3) 死锁/忙等待恶化** - 高优先级进程中的忙等待循环更难被抢占: ```c while (1) { /* 无sleep的系统调用 */ } // 优先级高时会导致死锁 ``` #### 3. 排查步骤 **(1) 优先级验证** ```bash ps -eo pid,class,rtprio,ni,pri,cmd | grep <进程名> # 查看实际优先级 ``` **(2) 资源监控** ```bash top -p <PID> # 观察CPU占用率 pidstat -p <PID> 1 # 监控上下文切换频率 perf sched latency # 分析调度延迟 ``` **(3) 代码审查要点** - 检查是否存在未释放的锁 - 确认I/O操作是否设置超时 - 验证循环中是否有调度点(如`poll()`, `sched_yield()`) #### 4. 解决方案 **(1) 优先级调整建议** - 实时优先级不超过90(保留部分资源给内核) - 使用`SCHED_RR`替代`SCHED_FIFO`(允许时间片轮转) ```c param.sched_priority = 85; sched_setscheduler(0, SCHED_RR, &param); // 更安全的设置 ``` **(2) 添加调度点** ```c while (1) { // 业务逻辑 usleep(1000); // 每1ms主动让出CPU sched_yield(); // 或显式让出调度 } ``` **(3) 系统限制调整** ```bash sysctl -w kernel.sched_rt_runtime_us=950000 # 设置实时进程最大CPU时间(微秒) echo <PID> > /sys/fs/cgroup/cpu/tasks # 通过cgroup限制资源 ``` **(4) 调试方法** - 触发卡死后通过SysRq强制转储: ```bash echo t > /proc/sysrq-trigger # 生成内核栈转储 crash /usr/lib/debug/boot/vmlinux /var/crash/<dump> # 分析转储文件 ``` #### 5. 预防措施 - 在`/etc/security/limits.conf`中设置用户级限制: ```conf @developers hard rtprio 90 # 限制用户组最大实时优先级 ``` - 使用`cgroups v2`进行资源隔离: ```bash mkdir /sys/fs/cgroup/test echo "100000 100000" > /sys/fs/cgroup/test/cpu.max # 限制100ms周期 ``` 通过逐步验证优先级设置、添加适当的调度点、配置系统级限制,可有效避免因优先级调整导致进程卡死问题。实际调试时建议使用`ftrace`跟踪调度事件: ```bash echo function_graph > /sys/kernel/debug/tracing/current_tracer echo sched_switch >> /sys/kernel/debug/tracing/set_event cat /sys/kernel/debug/tracing/trace_pipe # 实时查看调度事件 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值