Domando o wp-cron.php

Problemas com o wp-cron podem levar o servidor a sobrecargas absurdas. Aqui detalhamos como resolvemos uma incidência dessas.

É comum na atividade diária de administração de servidores precisar lidar com sobrecargas, bloqueios, ataques de “hackers”, de spammers, e outras situações mais ou menos preocupantes. Basicamente, o que se espera é que os sites do cliente estejam carregando rapidamente, sem erros, e permitindo a ele satisfazer as necessidades de seus usuários e leitores, o que indica que estamos obtendo sucesso em nossa missão.

Hoje pela manhã enfrentamos uma situação bastante estranha, incomum, que vamos relatar agora, tanto a título de curiosidade quanto para que nossos clientes que venham a passar por este problema possam se prevenir.

Os tópicos que abordaremos serão:

  • esgotamento de espaço em disco no servidor;
  • MySQL sobrecarregado;
  • script wp-cron.php consumindo 100% de processador;
  • solução de todos os problemas acima.

Servidor com espaço em disco esgotado

Quando recebemos o chamado de nosso cliente reclamando que o seu site não abria (embora ele não necessariamente estivesse perdendo visitas, graças à ação da CloudFlare), a primeira coisa que notamos no servidor foi uma carga de processamento altíssima, no mínimo 50x acima do normal, e o total esgotamento do espaço em disco (evidenciado, entre outros sintomas, pela negativa do cPanel de carregar).

Investigando o problema descobrimos que o MySQL havia gerado, durante a madrugada, mais de 140GB de logs de erro!

Registro de consultas lentas no MySQL

Na PortoFácil mantemos o registro das consultas (queries, para usar o termo em Inglês e mais adequado, em nossa humilde opinião) que demoram mais de um segundo para executar no MySQL. Este registro permite a identificação de potenciais problemas de arquitetura das tabelas de banco de dados dos aplicativos dos clientes, fornece informações que ajudam no processo de “afinar” um servidor, e — o mais importante e frequente de todos os benefícios — facilita a tarefa de identificar plugins mal comportados que possam estar acabando com o desempenho de uma máquina.

No caso que estamos relatando, este registro de queries lentas estava com mais de 140GB de tamanho, levando os serviços e processos normais da máquina à inoperância.

Ao excluir os 140GB de logs o servidor voltou a funcionar, mas a sobrecarga não cedia.

MySQL sobrecarregado

Domando o wp-cron.phpAo analisar a lista de processos da máquina identificamos, para nossa tristeza, que o vilão era o MySQL, que consumia 100% de uma CPU (a máquina em questão tem quatro) e mais de 80% de uma outra.

Procedemos aos “rituais” costumeiros de reparar e otimizar bancos de dados, verificar arquivo de configuração e nada parecia fora do normal.

O problema permanecia.

wp-cron.php consumindo toda a CPU possível

Analisando mais detidamente a lista de processos verificamos que os scripts do WordPress estavam sendo executados, e que havia dezenas de sessões do wp-cron.php rodando simultaneamente. Não por acaso, eram do processamento deste arquivo que vinha a maioria das entradas do registro de queries lentas.

A fim de testar, “matamos” o serviço de HTTP da máquina, e os scripts em PHP. Instantaneamente o consumo de CPU saiu dos 400% (quatro CPUS a 100% cada uma) para uma insignificância qualquer acima de zero.

Restituímos o HTTP, e as CPUs voltaram ao máximo de processamento, e novamente os mesmos processos no topo dos violentadores de processador.

O que é o wp-cron.php

Todo WordPress conta com um script chamado wp-cron.php, cuja função é executar tarefas agendadas no blog: publicação de posts, envio de avisos, backups (péssima ideia, diga-se de passagem), “tweets” aleatórios, e muitas outras possibilidades.

O problema é que a maneira como o WP-Cron é implementado pode não ser das mais espertas: cada vez que uma página ou post do blog é carregado e não esteja no cache, o script wp-cron.php é chamado, e dependendo de algumas condições (esotéricas nesse momento) ele executa ou não as tarefas programadas.

Race condition

Race condition é uma situação que ocorre quando um determinado programa (para usar o termo mais genérico possível) começa a rodar uma outra cópia de si mesmo antes que a cópia anterior tenha terminado de executar.

O wp-cron.php, infelizmente, não é muito esperto no que diz respeito a evitar as race conditions, que estavam evidenciadas pela quantidade de processos de wp-cron.php ativos simultaneamente.

Desativando o WP-Cron

O primeiro passo para acabar com as race conditions e devolver a saúde para o site do cliente foi desativar o mecanismo interno do WP-Cron.

Este objetivo é facilmente alcançado pela adição de uma única linha ao wp-config.php do blog:

define('DISABLE_WP_CRON', true);

Ao fazer esta modificação simples o site do cliente voltou a ficar extremamente rápido, devolvendo a experiência de navegação confortável aos leitores dele.

Reativando o WP-Cron da maneira correta

Entretanto, o WordPress precisa do WP-Cron, embora sua implementação padrão não seja das melhores.

Os cronjobs do Linux

O Linux, sistema operacional que utilizamos em nossos servidores, conta com o recurso dos cronjobs, que permite programar dia e hora em que tarefas repetitivas serão executadas. Não fosse a necessidade de o WordPress adaptar-se aos mais variados ambientes (alguns em que o usuário nem tem o direito de executar tarefas agendadas), certamente eles não reinventariam a roda ao implementar uma “cron” interna.

Com os cronjobs do Linux temos controle do intervalo entre cada execução (sem gambiarras, a partir de uma vez por minuto, o que na maioria dos casos já evita a race condition).

Basta acrescentar a seguinte tarefa na cron (o que pode ser facilmente feito pelo cPanel):

* * * * * /usr/bin/wget http://www.domínio.com/wp-cron.php?doing_wp_cron -O /dev/null > /dev/null 2>&1

O código acima deve estar todo em uma única linha, o que o cPanel obriga a fazer na hora de criar a tarefa agendada.

Na maioria dos casos, a tarefa cron pode ser substituída com vantagens (em termos de gerenciamento) instalando um plugin qualquer do tipo “missing schedule”, já que a tarefa mais importante que o WP-Cron precisa executar é a publicação automática de posts agendados.

Conclusão

Após efetuadas as alterações acima indicadas, o servidor de nosso cliente voltou a ter um desempenho excelente, seu site passou a carregar até mais rapidamente do que antes, devido ao fato de não haver mais desperdício de ciclos de CPU em tarefas desnecessárias.

Caso você venha precisar aplicar estas técnicas em seu servidor, não se preocupe em decorar tudo isso: abra um chamado de suporte, explique a situação, e tomaremos conta direitinho do seu servidor.

 

Quero ser cliente da PortoFácil!Contato

Avalie este conteúdo!

Avaliação média: 4.36
Total de Votos: 22

Domando o wp-cron.php

Compartilhe

Publicado por Janio Sarmento – 28 de abril de 2017