Resposta personalizada do LInux OOM

6

Estou executando o servidor da web Apache e gostaria de melhorar um pouco como a situação da OOM é tratada.

Sou avare das pontuações OOM e já fiz algumas personalizações nesse assunto, então quando algo de ruim acontece, o Linux está matando os processos corretos. Mas não é o suficiente.

O problema é que, às vezes, quando ocorre OOM, o servidor fica sobrecarregado e depois trava e deve ser reiniciado. Eu gostaria de lidar com isso sem o reinício completo do servidor. Então eu preciso de alguma forma "ligar" um script na invocação killer da OOM que mataria todos os processos do apache (e seus CGIs), liberando a memória e iniciando-a novamente (Apache).

Eu sei que isso funcionaria, porque se a OOM ocorrer e eu for rápido o suficiente para fazer o login no servidor e matar o Apache manualmente, tudo está OK então.

FYI Estou executando agora quase uma centena desses servidores, e é por isso que estou procurando uma solução totalmente automática.

Uma solução possível seria, claro, usar algum watchdog que analise o syslog e detecte OOMs dessa maneira - eu já tenho algo parecido, que informa sobre os assassinatos de OOM por e-mail. Essa abordagem pode resolver algumas situações, mas se a OOM estiver realmente ruim, o servidor está sobrecarregado demais e meu script nem sequer é iniciado (é executado pelo cron). Ele pode ser melhorado usando inotify para assistir ao syslog ou canalizar o syslog diretamente (ou seja, pelo fifo) para o script.

Mas ainda estou pensando - não há como "ligar" o script diretamente ao assassino da OOM? Então eu colocaria algo assim em algum arquivo / etc / ..:

oom_action="sh /path/to/my/script.sh kill"

Ou simplesmente não é possível fazer assim?

Estou usando o Centos 6, Apache 2.2 e PHP como FastCGI.

    
por dave 28.04.2015 / 09:52

4 respostas

0

Como eu não encontrei nenhuma solução melhor, eu implementei o watchdog para ler as mensagens do syslog do kernel (via fifo):

/etc/rsyslog.d:

(...)
kern.err         |/path/to/fifo

e pesquise-os pela atividade OOM-killer:

while read /path/to/fifo; do (..)

e quando o OOM-killer desova maciçamente (eu realmente preciso verificar apenas para situações de emergência), eu mato (e então inicio) o Apache.

    
por 05.05.2015 / 16:20
3

Por que você não monitora os processos do apache e define seu valor oom_adj para 15 para ter certeza de que eles serão os primeiros a serem encerrados no OOM? Aqui estão algumas instruções sobre essa configuração.

Dependendo da sua configuração, você pode modificar os scripts de inicialização do apache ou configurar uma tarefa Cron simples para fazer isso.

Você também pode observar periodicamente a saída do comando dmesg | grep -i oom . Se houver alguma linha, o OOM killer matou alguém desde que o servidor foi inicializado pela última vez. Você pode então limpar o buffer com dmesg --clear

    
por 05.05.2015 / 14:03
0

Eu sei que existem aplicativos PHP horríveis no mundo, muitos deles, mas não existe algo que você poderia fazer no lado do Apache / FastCGI / PHP? Apache constantemente OOMing não é algo que você deve encontrar com muita freqüência.

Tente diminuir o número máximo de processos Apache e os manipuladores FastCGI, e veja se suas configurações atuais do php.ini são muito altas para o máximo de memória por script.

Além disso, é perfeitamente possível usar ulimit com o Apache e restringir o número de memória que um processo pode usar. Isso pode ajudá-lo antes que o servidor quase morra em espiral.

OOM é o último recurso, e tudo o que pode levá-lo deve ser inspecionado.

    
por 05.05.2015 / 15:34
0

Acho melhor você colocar seu processo no subconjunto de memória do cgroup e usar o release_agent para chamar um script externo quando a memória ocorrer

notify_on_release
    contains a Boolean value, 1 or 0, that either enables or disables the execution of the release agent. If the notify_on_release is enabled, the kernel executes the contents of the release_agent file when a cgroup no longer contains any tasks (that is, the cgroup's tasks file contained some PIDs and those PIDs were removed, leaving the file empty). A path to the empty cgroup is provided as an argument to the release agent. 

release_agent (present in the root cgroup only)
    contains a command to be executed when a “notify on release” is triggered. Once a cgroup is emptied of all processes, and the notify_on_release flag is enabled, the kernel runs the command in the release_agent file and supplies it with a relative path (relative to the root cgroup) to the emptied cgroup as an argument. The release agent can be used, for example, to automatically remove empty cgroups

Usando o cgroup, você pode controlar quanto recurso você pode usar e não sobrecarregar o servidor

Using cgroup you can control the server resources
    
por 05.05.2015 / 18:28