Eu tenho um servidor Debian 10 rodando Apache2 2.4.38. Recentemente, substituí o arquivo de certificado SSL usado por todos os vhosts HTTPS configurados e executei systemctl reload apache2.service
, que é executado /usr/sbin/apachectl graceful
por meio do arquivo systemd unit.
De acordo com os documentos do Apache 2,
O USR1 ou sinal normal faz com que o processo pai avise os filhos para sair após a solicitação atual (ou sair imediatamente se não estiver atendendo a nada). O pai relê seus arquivos de configuração e reabre seus arquivos de log. À medida que cada filho morre, o pai o substitui por um filho da nova geração da configuração, que começa a atender novas solicitações imediatamente.
Em um servidor ocupado, é compreensível que ocorram atrasos na substituição de um processo filho. No entanto, hoje notei que raramente o servidor ainda responderá com o antigo certificado SSL pré-substituição. Eu fui e dei uma olhada nos processos:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 13559 0.0 0.2 15640 10356 ? Ss 2022 18:53 /usr/sbin/apache2 -k start
www-data 16834 0.7 0.6 1232452 27780 ? Sl 06:00 3:47 /usr/sbin/apache2 -k start
www-data 17415 0.9 0.6 1231844 26532 ? Sl 10:22 2:32 /usr/sbin/apache2 -k start
www-data 17552 0.7 0.6 1231736 26376 ? Sl 10:53 1:47 /usr/sbin/apache2 -k start
www-data 17612 0.6 0.6 1232000 26840 ? Sl 10:54 1:34 /usr/sbin/apache2 -k start
www-data 17641 0.6 0.5 1231980 22732 ? Sl 10:54 1:36 /usr/sbin/apache2 -k start
www-data 17642 0.8 0.6 1231848 24728 ? Sl 10:54 1:59 /usr/sbin/apache2 -k start
www-data 26704 0.5 0.6 1232216 24748 ? Sl Jan18 89:53 /usr/sbin/apache2 -k start
O último processo da lista se destaca nas colunas START
e TIME
. Executei o comando reload em 24 de janeiro, mas agora, seis dias depois, esse processo ainda está em andamento. O servidor está respondendo às solicitações muito bem, no entanto - não se sabe se esse trabalhador está realmente atendendo a novas solicitações ou não, mas os outros estão.
A configuração do servidor é simples e padrão o suficiente para não ser incluída aqui (por enquanto – se precisar de alguma informação específica, pergunte). A única característica interessante sobre ele é que ele está rodando mod_jk, ou seja, as várias VirtualHost
diretivas possuem JkMount /* workername
(onde workername
está definido em /etc/libapache2-mod-jk/workers.properties). mod_jk usa ajp13
para se conectar a um dos dois servidores de aplicativos com balanceamento de carga executando o Tomcat.
Esta não é a primeira vez que tivemos um trabalhador Apache2 travado, mas nunca consegui determinar o motivo pelo qual acabou dessa forma. Pode ter algo a ver com mod_jk e os aplicativos Java (muito) herdados, possivelmente havendo alguma solicitação que causou um raro bug de caso extremo no nível Java/mod_jk e está impedindo que o trabalhador seja capaz de sair por meio do USR1 sinal. Os logs do aplicativo Java não estão sob meu controle; eles são extremamente detalhados com informações inúteis, muitas vezes faltando carimbos de data/hora e são praticamente inúteis para fins de solução de problemas, a menos, talvez, se você os estivesse olhando no momento exato em que o erro ocorreu.
Terei que fazer uma reinicialização não otimizada, mesmo que isso cause uma pequena interrupção na produção, mas estou interessado em outros métodos para depurar esse problema no futuro, para que possamos fazer com que os trabalhadores sempre executem uma reinicialização otimizada de maneira confiável quando necessário. Como podemos analisar melhor o que faz um trabalhador ficar preso assim?
Os resultados de apachectl -V
:
Server version: Apache/2.4.38 (Debian)
Server built: 2021-12-21T16:50:43
Server's Module Magic Number: 20120211:84
Server loaded: APR 1.6.5, APR-UTIL 1.6.1
Compiled using: APR 1.6.5, APR-UTIL 1.6.1
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="mime.types"
-D SERVER_CONFIG_FILE="apache2.conf"
apachectl -S
com subdomínios de produção redigidos:
VirtualHost configuration:
*:443 is a NameVirtualHost
default server vhost1.domain.example (/etc/apache2/sites-enabled/00_vhost1.domain.example-ssl.conf:2)
port 443 namevhost vhost1.domain.example (/etc/apache2/sites-enabled/00_vhost1.domain.example-ssl.conf:2)
port 443 namevhost vhost2.domain.example (/etc/apache2/sites-enabled/01_vhost2.domain.example-ssl.conf:2)
port 443 namevhost vhost3.domain.example (/etc/apache2/sites-enabled/02_vhost3.domain.example-ssl.conf:2)
port 443 namevhost vhost4.domain.example (/etc/apache2/sites-enabled/03_vhost4.domain.example-ssl.conf:2)
alias alias1.domain.example
*:80 is a NameVirtualHost
default server vhost1.domain.example (/etc/apache2/sites-enabled/00_vhost1.domain.example.conf:1)
port 80 namevhost vhost1.domain.example (/etc/apache2/sites-enabled/00_vhost1.domain.example.conf:1)
port 80 namevhost vhost2.domain.example (/etc/apache2/sites-enabled/01_vhost2.domain.example.conf:1)
alias 172.16.33.63
port 80 namevhost vhost3.domain.example (/etc/apache2/sites-enabled/02_vhost3.domain.example.conf:1)
port 80 namevhost vhost4.domain.example (/etc/apache2/sites-enabled/03_vhost4.domain.example.conf:1)
alias alias1.domain.example
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex default: dir="/var/run/apache2/" mechanism=default
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: using_defaults
Mutex ssl-stapling-refresh: using_defaults
Mutex ssl-stapling: using_defaults
Mutex proxy: using_defaults
Mutex ssl-cache: using_defaults
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33
Group: name="www-data" id=33