问题背景:基于golang 实现了一个自助化配置的通用命令任务管理模块,这样运营人员可以直接通过修改配置,完成 if do 的命令逻辑:当磁盘满时,做什么?当网卡down 时做什么;并且可以支持各类环境 和规则。

确定僵尸进程问题
但是灰度后不久,命令执行报错: fork exec resource temporarily unavailable;
进一步查看syslog 报错 fork rejected by pids controller in xxx.service,cat pid limits 查看上限,也就是说,进程fork 出错 service 控制上限了
执行 ps -ef |grep -c pid 发现service 创建了太多进程 ,大部分都变成了Z状态,另外通过top 也可以看到 zombile 个数

我们知道僵尸进程是子进程退出,父进程没有wait 捕捉状态;配置了多个命令,每分钟 每30秒执行一次,为什么大部分僵尸进程是 wc 和grep 呢?即:不是所有命令执行变成了僵尸进程,而是某一部分命令变成了僵尸。
通过分析这些特殊的命令有助于缩小命令调用变僵尸进程的bug代码范围:

确定僵尸进程的命令特征
一种方式是:注释配置 使用排除法,但是效率太低;
另一种方式使用动态追踪方式 来查看具体僵尸进程(不断在产生),以grep僵尸进程为例:
python execsnoop.py -n grep -T |grep 父进程 -B 1
execsnoop 通过getppid,/proc/pid/status 中的ppid 来获取父进程,但是有时候命令马上执行完就退出了,难以获取祖父进程等,另外获取打印参数也是一个问题;实际上 有时候我们需要追踪到最开始的进程,因此稍作修改:

    for (int i = 0; curr_pid != 1 && i < MAX; i++) {curr = curr->real_parent;curr_pid = curr->tgid;data.ppid[i] = curr_pid;bpf_probe_read(&c, sizeof(c), curr->comm);comm_cache.update(&curr_pid, &c);}

cmd pipeline 的问题
从上一步 可以明确是 cmd pipeline 的问题;当pipe line 的命令都执行成功时,不会出现Z,但是当前面有进程异常退出时,后面的wc 等命令出现了Z
https://stackoverflow.com/questions/36050503/golang-child-processes-become-zombies

func RunCmds(maxtime int, cmds []*exec.Cmd) error {// start processes in descending orderfor i := len(cmds) - 1; i > 0; i-- {cmds[i].SysProcAttr = &syscall.SysProcAttr{Setpgid: true}if maxtime == 0 {maxtime = 600}time.AfterFunc(time.Duration(maxtime)*time.Second, func() {if cmds[i].Process != nil {syscall.Kill(-cmds[i].Process.Pid, syscall.SIGINT)syscall.Kill(-cmds[i].Process.Pid, syscall.SIGKILL)}})if err := cmds[i].Start(); err != nil {return err} }// run the first processif err := cmds[0].Run(); err != nil {return err}// wait on processes in ascending orderfor i := 1; i < len(cmds); i++ {if err := cmds[i].Wait(); err != nil {return err}}return nil
}

仔细阅读:start run wait 接口:
start 会调用os.StartProcess 创建一个新的进程 也是cmd.Process, 而wait 相当于等待子进程退出 清理资源,wait 等待子进程退出 或者 stdin stdout copy complete. 所以类似wc -l 等命令得以继续等待stdin 而不退出,但是直接wait 会 使得wc -l 退出(待确认)

所以一定要 wait start后的进程,否则会产生僵尸进程,pipeline 更好实现方式可以参考 上面stackoverflow 连接

如何通过扩展自己的知识面来提升工作效率;单纯的动态追踪命令,仅在排查谁调用了命令时使用,想不到在排查命令导致的僵尸进程时正好可以用到

golang exec cmd pipeline zombile 进程相关推荐

  1. Java执行cmd命令启动进程

    Java执行cmd命令启动进程 1.代码 //execute command through java applicationpublic static void exeCmd(){Runtime r ...

  2. Linux系统编程--3(exec 函数族,僵尸进程和孤儿进程,wait和wait_pid回收子进程)

    exec 函数族 fork 创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支) ,子进程往往要调用一种 exec 函数以执行另一个程序.当进程调用一种 exec 函数时,该进程的用户 ...

  3. Linux 高并发学习笔记 - exec 函数簇重载进程

    2.2.4 exec 函数簇重载进程 Linux 高并发学习笔记 - 笔记索引 execl.execlp.execle.execv.execvp.execvpe exec函数簇将重载进程,直接覆盖当前 ...

  4. golang exec.Command 执行命令 返回详细错误信息

    当我运行下面的代码: cmd := exec.Command("find","/","-maxdepth","1",&q ...

  5. window cmd 端口查进程

    如何查看程序占用的端口 一. 查看所有进程占用的端口  在开始-运行-cmd,输入:netstat –ano可以查看所有进程 二.查看占用指定端口的程序  当你在用tomcat发布程序时,经常会遇到端 ...

  6. 【golang】golang使用cmd去ping网址在window和linux的区别

    设置ping的次数,在linux和window上,命令内容不一样 window ping -n 2 php-china.com linux ping -c 2 php-china.com //设置类型 ...

  7. 结束拒绝访问的进程 cmd下结束进程 强行结束进程

    结束拒绝访问的进程 有些病毒和恶意进程我们在任务管理器里面是不能结束的,这个时候,如果又没有工具,就很麻烦了,今天看网管员世界,提到了一种方法,能够解决: 根本的思想是用system的权限来运行tas ...

  8. c语言调用cmd隐藏黑窗口,golang 调用cmd下程序隐藏黑窗口-方法1

    通过go的标准库exec调用cmd命令时会闪弹黑窗口,为解决此问题在windows下可以用win32 API 的 WinExec. 此问题主要出现在带UI或无控制台的程序调用cmd时. 编译go时加入 ...

  9. 结束拒绝访问的进程 cmd下结束进程 强行结束进程 1

    结束拒绝访问的进程 有些病毒和恶意进程我们在任务管理器里面是不能结束的,这个时候,如果又没有工具,就很麻烦了,今天看网管员世界,提到了一种方法,能够解决: 根本的思想是用system的权限来运行tas ...

最新文章

  1. 使用神经网络做二分类,输出层需要几个神经元?应该选择哪一种激活函数?如果要处理minst数据、输出层需要几个神经元?使用那种激活函数?如果使用神经网络预测房价,输出层需要几个神经元、使用什么激活函数?
  2. 2019年度最全IT吃瓜指南
  3. 深入理解 SpringBoot 启动机制(starter 机制)
  4. testng入门教程5TestNG套件测试
  5. 奉劝各位的atas几句话,别怪我没提醒
  6. boost::mp11::mp_find相关用法的测试程序
  7. JUC原子类-类成员(五)
  8. 开源Easydarwin流媒体服务器Windows编译、配置、部署
  9. 数据库创建存储过程_创建存储过程来修复孤立的数据库用户
  10. VLAN aggregation(vlan聚合)配置
  11. cass生成曲线要素_使用CASS6_0获取道路平曲线测设元素的解决方案.pdf
  12. BeetlSQL 注解
  13. ACM 6174问题Java解决
  14. 小程序下载图片、文件、wx.downloadFile,废话少说直接上代码
  15. 值得学习的开源web项目
  16. Android 数据加密算法总结
  17. linux scp传输文件权限被拒绝,Linux的远程传输文件scp及出现Permission denied (publickey).lost connection问题解决方法...
  18. 算法-----一苇渡江
  19. HTML 之 br 标签
  20. 小白安装Revit2021的Lookup和Manager文件步骤(附文件)

热门文章

  1. HTML5的data-*自定义属性
  2. Android 数据库基本操作-2
  3. Readline-select
  4. go 读取 json 配置文件
  5. 从Storm到Flink:大数据处理的开源系统及编程模型
  6. MySQL 中 6 个常见的日志问题
  7. 新项目入手-》解决方案之一
  8. centos下配置nginx支持php
  9. 实验02 Linux文件和目录管理
  10. Oracle:管理 date类型 interval 动态变化的分区:查询、删除