Solaris 上的 Apache v2.4.56,带有 libapr 1.6.2。启动时,它会生成 5 个 httpd 进程。
有时服务器会挂起,不接受请求。甚至无法连接到端口 80。
我对这 5 个进程中的每一个都进行了核心转储,发现其中两个似乎卡在同一个函数 write() 中。我猜它们正在将事件写入日志文件,但我不确定。以下是我配置日志的方式:
ErrorLog /data/log/HTTP.apache.log
LogLevel info
<IfModule log_config_module>
LogFormat "%h %f %t \t%I \t%O \t%D" common
CustomLog "|/usr/bin/logger -tHTTP -pdaemon.info" common
</IfModule>
以下是第一个看似死锁的进程的调用堆栈的示例:
------------ lwp# 6 / thread# 6 ---------------
ffffffff730cb048 write (b, ffffffff7e75b9ff, 1)
ffffffff57d28ca8 apr_file_write (0x100267338?, 0xffffffff7e75b9ff?, 0xffffffff7e75b9e0?, 0x0?, 0x0?, 0x0?) + 1c8
ffffffff57d28ff4 apr_file_putc (0x1?, 0x100267338?, 0x0?, 0x0?, 0x1?, 0x0?) + 1c
ffffffff57d392c8 apr_pollset_wakeup (0x100266a50?, 0x0?, 0x0?, 0x0?, 0x100266a18?, 0x0?) + 20
00000001000b4888 TO_QUEUE_APPEND (0x100221228?, 0x10032b700?, 0x0?, 0x0?, 0x100221258?, 0x10032b7b0?) + f0
00000001000b6f5c process_socket (0x1002675c0?, 0x10032b378?, 0x10032b400?, 0x0?, 0x1?, 0x3?) + 8bc
00000001000ba14c worker_thread (0x1002675c0?, 0x100215af0?, 0xffffffff7f582240?, 0xfffc00?, 0x1?, 0x3?) + 494
ffffffff57d407a0 dummy_worker (0x1002675c0?, 0x0?, 0x1?, 0xffffffff57d40788?, 0x0?, 0x0?) + 18
ffffffff730c58b4 _lwp_start (0x0?, 0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
第二个进程的堆栈完全相同。
令我惊讶的是,在 libapr 的 apr_file_write() 源代码中,调用 write() 函数时没有锁定机制。
您知道什么可能导致死锁吗?问题出在将 CustomLog 与管道结合使用的配置上吗?