我有一台运行 Apache2 2.4.38 的 Debian 10 服务器。最近,我替换了所有配置的 HTTPS 虚拟主机使用的 SSL 证书文件并运行systemctl reload apache2.service
,它/usr/sbin/apachectl graceful
通过 systemd 单元文件运行。
根据 Apache 2 文档,
USR1 或优雅信号导致父进程建议子进程在当前请求后退出(或者如果他们没有提供任何服务则立即退出)。父级重新读取其配置文件并重新打开其日志文件。当每个孩子死亡时,父母会用新一代配置中的孩子替换它,它会立即开始为新请求提供服务。
在繁忙的服务器上,替换子进程时发生延迟是可以理解的。然而,今天我注意到服务器很少会仍然使用旧的、替换前的 SSL 证书进行响应。我去看看流程:
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
START
列表中的最后一个进程在和列上突出显示TIME
。我在 1 月 24 日运行了重新加载命令,但现在,六天后,这个过程仍在进行。不过,服务器对请求的响应很好——不知道这名工作人员是否真的在处理新请求,但其他工作人员是。
服务器配置很简单,默认情况下不会包含在这里(现在 - 如果您需要任何特定信息,请询问)。唯一有趣的特性是它运行 mod_jk,即各种VirtualHost
指令都有JkMount /* workername
(workername
定义在 /etc/libapache2-mod-jk/workers.properties 中)。mod_jk 用于ajp13
连接到运行 Tomcat 的两个负载平衡应用程序服务器之一。
这不是我们第一次遇到 Apache2 worker 卡住的情况,但我一直无法确定它以这种方式结束的原因。这可能与 mod_jk 和(非常)遗留的 Java 应用程序有关,可能有一些请求在 Java/mod_jk 级别导致罕见的边缘情况错误,并阻止工作人员通过 USR1 退出信号。Java 应用程序日志不在我的控制之下;它们非常冗长,包含毫无意义的信息,通常缺少时间戳,并且对于故障排除几乎毫无用处,除非您恰好在错误发生的那一刻正在查看它们。
我将不得不进行非优雅重启,即使它会导致轻微的生产中断,但我对将来调试此问题的更多方法感兴趣,以便我们可以让工作人员始终可靠地执行优雅重启需要的时候。我们如何才能更好地分析是什么让工人陷入困境?
结果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
编辑了生产子域:
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
第三方模块存在多个问题,不允许 httpd 优雅地重新启动子进程,甚至导致服务器无响应。
我对 mod_weblogic (mod_wl_24.so) 有类似的行为,其他一些人报告了与 mod_security 类似的行为。Apache HTTPD 开发人员曾尝试解决第三方模块中这些假定的错误行为。
例如 2.4.4X 对此有几个修复。我会尝试至少升级到 2.4.49 及更高版本,然后再试一次。检查https://downloads.apache.org/httpd/CHANGES_2.4并寻找“mpm_event”。
如果您不能立即升级,也有可能使用 mod_proxy_ajp 获得更好的结果。
简而言之,答案是:如果您使用的是第三方模块,请尝试将版本至少升级到 2.4.49。