是什么杀死了我的过程,为什么?

我的应用程序在Linux上作为后台进程运行。它当前在终端窗口的命令行中启动。

最近,一个用户执行了一段时间的应用程序,它神秘地死亡了。文本:

杀死

是在终端上。这种情况发生了两次。我问是否有人在不同的终端使用杀死命令来杀死进程?没有。

Linux在什么条件下会决定杀死进程?shell显示的是已杀死,因为进程在收到k(9)信号后死亡了。如果Linux发送了k信号,系统日志中是否应该有解释它被杀死的原因的消息?

538844 次浏览

用户有能力杀死自己的程序,使用mi或Control+C,但我得到的印象不是发生了什么,用户向你抱怨。

root当然有杀死程序的能力,但是如果有人在你的机器上有root并且正在杀死东西,你就会有更大的问题。

如果您不是系统管理员,系统管理员可能已经在CPU、RAM、ort磁盘使用和超过它们的自动终止进程上设置了配额。

除了这些猜测,我不确定没有关于该计划的更多信息。

如果用户或系统管理员没有杀死内核可能拥有的程序。内核只会在极端资源短缺(想想mem+交换耗尽)等特殊情况下杀死进程。

我们在客户站点(我认为是Red Hat)的Linux下经常遇到问题,OOMKiller(内存不足杀手)杀死了我们的主要应用程序(即服务器存在的原因)和它的数据库进程。

在每种情况下,OOMKiller只是简单地决定进程正在使用大量资源……机器甚至不会因为缺乏资源而失败。应用程序和它的数据库都没有内存泄漏(或任何其他资源泄漏)的问题。

我不是Linux专家,但我收集了决定何时杀死某些东西的算法,并且杀死什么是复杂的。此外,我被告知(我不能说这是否准确)OOMKiller被烘焙到内核中,你不能简单地不运行它。

这看起来像是一篇关于这个主题的好文章:驯服OOM杀手1)。

要点是Linux超额内存。当一个进程要求更多的空间时,Linux会给它那个空间,即使它被另一个进程占用,前提是没有人实际使用他们要求的所有内存。该进程将在实际使用时独占使用它分配的内存,而不是在它要求时独占使用它分配的内存。这使得分配很快,并且可能允许你“作弊”并分配比实际拥有的更多的内存。然而,一旦进程开始使用这块内存,Linux可能会意识到它在分配它没有的内存方面过于慷慨,并且将不得不杀死一个进程来释放一些内存。要杀死的进程是基于一个分数,考虑了运行时(长时间运行的进程更安全)、内存使用(贪婪的进程不太安全)和一些其他因素,包括一个你可以调整以降低进程被杀死的可能性的值。这一切都在文章中进行了更详细的描述。

编辑:这里是[另一篇文章]2),它很好地解释了如何选择进程(用一些内核代码示例进行注释)。关于这一点的伟大之处在于它包含了对各种badness()规则背后的推理的一些注释。

在lsf环境(交互式或其他方式)中,如果应用程序的内存利用率超过队列上管理员预设的阈值,或者提交到队列中的资源请求,则进程将被杀死,以便其他用户不会成为潜在运行的受害者。它在发送电子邮件时并不总是发送电子邮件,具体取决于它的设置方式。

在这种情况下,一种解决方案是查找具有较大资源的队列或在提交中定义较大的资源需求。

您可能还想查看man ulimit

虽然我不记得ulimit导致Killed,但自从我需要它以来已经有一段时间了。

PAM模块限制资源导致了您所描述的结果:我的进程神秘地死亡,控制台窗口上有文本杀死syslogkern.log都没有日志输出。顶部程序帮助我发现,在CPU使用一分钟后,我的进程就被杀死了。

我最近遇到了这个问题。最后,我发现我的进程在Opensuse zypper更新被自动调用后被杀死。禁用zypper更新解决了我的问题。

尝试:

dmesg -T| grep -E -i -B100 'killed process'

其中-B100表示杀死发生前的行数。

在Mac OS上省略-T

正如dwc和Adam Jaskiewicz所说,罪魁祸首很可能是OOM杀手。然而,接下来的问题是:我如何防止这种情况?

有几种方法:

  1. 如果可以,请为您的系统提供更多RAM(如果是VM,则很容易)
  2. 确保OOM杀手选择不同的过程。
  3. 禁用OOM杀手
  4. 选择一个禁用OOM Killer的Linux发行版。

我发现(2)特别容易实现,这要归功于这篇文章

一个像sytap(或跟踪程序)这样的工具可以监控内核信号传输逻辑和报告。

# stap --example sigmon.stp -x 31994 SIGKILL
SPID     SNAME            RPID  RNAME            SIGNUM SIGNAME
5609     bash             31994 find             9      SIGKILL

该脚本中的过滤if块可以调整为味道,或消除以跟踪系统范围的信号流量。可以通过收集回溯来进一步隔离原因(分别为内核和用户空间向探测添加print_backtrace()和/或print_ubacktrace())。

这是Linux内存溢出管理器(OOM)。选择您的进程是因为“不良”-最近、驻留大小(正在使用的内存,而不仅仅是分配的内存)和其他因素的组合。

sudo journalctl -xb

您将看到一条消息,例如:

Jul 20 11:05:00 someapp kernel: Mem-Info:
Jul 20 11:05:00 someapp kernel: Node 0 DMA per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:    0, btch:   1 usd:   0
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:  186, btch:  31 usd:  30
Jul 20 11:05:00 someapp kernel: active_anon:206043 inactive_anon:6347 isolated_anon:0
active_file:722 inactive_file:4126 isolated_file:0
unevictable:0 dirty:5 writeback:0 unstable:0
free:12202 slab_reclaimable:3849 slab_unreclaimable:14574
mapped:792 shmem:12802 pagetables:1651 bounce:0
free_cma:0
Jul 20 11:05:00 someapp kernel: Node 0 DMA free:4576kB min:708kB low:884kB high:1060kB active_anon:10012kB inactive_anon:488kB active_file:4kB inactive_file:4kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 968 968 968
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 free:44232kB min:44344kB low:55428kB high:66516kB active_anon:814160kB inactive_anon:24900kB active_file:2884kB inactive_file:16500kB unevictable:0kB isolated(anon):0kB isolated
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 0 0 0
Jul 20 11:05:00 someapp kernel: Node 0 DMA: 17*4kB (UEM) 22*8kB (UEM) 15*16kB (UEM) 12*32kB (UEM) 8*64kB (E) 9*128kB (UEM) 2*256kB (UE) 3*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 4580kB
Jul 20 11:05:00 someapp kernel: Node 0 DMA32: 216*4kB (UE) 601*8kB (UE) 448*16kB (UE) 311*32kB (UEM) 135*64kB (UEM) 74*128kB (UEM) 5*256kB (EM) 0*512kB 0*1024kB 1*2048kB (R) 0*4096kB = 44232kB
Jul 20 11:05:00 someapp kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
Jul 20 11:05:00 someapp kernel: 17656 total pagecache pages
Jul 20 11:05:00 someapp kernel: 0 pages in swap cache
Jul 20 11:05:00 someapp kernel: Swap cache stats: add 0, delete 0, find 0/0
Jul 20 11:05:00 someapp kernel: Free swap  = 0kB
Jul 20 11:05:00 someapp kernel: Total swap = 0kB
Jul 20 11:05:00 someapp kernel: 262141 pages RAM
Jul 20 11:05:00 someapp kernel: 7645 pages reserved
Jul 20 11:05:00 someapp kernel: 264073 pages shared
Jul 20 11:05:00 someapp kernel: 240240 pages non-shared
Jul 20 11:05:00 someapp kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
Jul 20 11:05:00 someapp kernel: [  241]     0   241    13581     1610      26        0             0 systemd-journal
Jul 20 11:05:00 someapp kernel: [  246]     0   246    10494      133      22        0         -1000 systemd-udevd
Jul 20 11:05:00 someapp kernel: [  264]     0   264    29174      121      26        0         -1000 auditd
Jul 20 11:05:00 someapp kernel: [  342]     0   342    94449      466      67        0             0 NetworkManager
Jul 20 11:05:00 someapp kernel: [  346]     0   346   137495     3125      88        0             0 tuned
Jul 20 11:05:00 someapp kernel: [  348]     0   348    79595      726      60        0             0 rsyslogd
Jul 20 11:05:00 someapp kernel: [  353]    70   353     6986       72      19        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  362]    70   362     6986       58      18        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  378]     0   378     1621       25       8        0             0 iprinit
Jul 20 11:05:00 someapp kernel: [  380]     0   380     1621       26       9        0             0 iprupdate
Jul 20 11:05:00 someapp kernel: [  384]    81   384     6676      142      18        0          -900 dbus-daemon
Jul 20 11:05:00 someapp kernel: [  385]     0   385     8671       83      21        0             0 systemd-logind
Jul 20 11:05:00 someapp kernel: [  386]     0   386    31573      153      15        0             0 crond
Jul 20 11:05:00 someapp kernel: [  391]   999   391   128531     2440      48        0             0 polkitd
Jul 20 11:05:00 someapp kernel: [  400]     0   400     9781       23       8        0             0 iprdump
Jul 20 11:05:00 someapp kernel: [  419]     0   419    27501       32      10        0             0 agetty
Jul 20 11:05:00 someapp kernel: [  855]     0   855    22883      258      43        0             0 master
Jul 20 11:05:00 someapp kernel: [  862]    89   862    22926      254      44        0             0 qmgr
Jul 20 11:05:00 someapp kernel: [23631]     0 23631    20698      211      43        0         -1000 sshd
Jul 20 11:05:00 someapp kernel: [12884]     0 12884    81885     3754      80        0             0 firewalld
Jul 20 11:05:00 someapp kernel: [18130]     0 18130    33359      291      65        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18132]  1000 18132    33791      748      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18133]  1000 18133    28867      122      13        0             0 bash
Jul 20 11:05:00 someapp kernel: [18428]    99 18428   208627    42909     151        0             0 node
Jul 20 11:05:00 someapp kernel: [18486]    89 18486    22909      250      46        0             0 pickup
Jul 20 11:05:00 someapp kernel: [18515]  1000 18515   352905   141851     470        0             0 npm
Jul 20 11:05:00 someapp kernel: [18520]     0 18520    33359      291      66        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18522]  1000 18522    33359      294      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18523]  1000 18523    28866      115      12        0             0 bash
Jul 20 11:05:00 someapp kernel: Out of memory: Kill process 18515 (npm) score 559 or sacrifice child
Jul 20 11:05:00 someapp kernel: Killed process 18515 (npm) total-vm:1411620kB, anon-rss:567404kB, file-rss:0kB

让我先解释一下何时以及为什么会调用OOMKiller?

假设您有512 RAM+1GB交换内存。所以理论上,您的CPU可以访问总共1.5GB的虚拟内存。

现在,一段时间以来,一切都在1.5GB的总内存内正常运行。但是突然(或逐渐)您的系统开始消耗越来越多的内存,并且达到了总内存使用的95%左右。

现在假设任何进程都从内核请求了大块内存。内核检查可用内存,发现它没有办法为你的进程分配更多内存。所以它将尝试释放一些内存调用/调用OOMKiller(http://linux-mm.org/OOM)。

OOMKiller有自己的算法来对每个进程进行排名。通常哪个进程使用更多内存就会成为被杀死的受害者。

我在哪里可以找到OOMKiller的日志?

通常在 /var/日志文件目录中。 /var/log/kern.log或 /var/log/dmesg

希望这对你有帮助。

一些典型解决方案:

  1. 增加内存(不交换)
  2. 查找程序中的内存泄漏并修复它们
  3. 限制任何进程可以消耗的内存(例如,JVM内存可以使用JAVA_OPTS限制)
  4. 查看日志和谷歌:)

在我的案例中,这发生在Laravel队列工作人员身上。系统日志没有提到任何杀死,所以我进一步查看,结果发现工作人员基本上是因为超过内存限制的作业而自杀(默认设置为128M)。

使用--timeout=600--memory=1024运行队列工作器为我解决了这个问题。