Apache mod_perl процессы зависают в состоянии futex_wait - PullRequest
3 голосов
/ 14 октября 2011

Я запускаю довольно популярную браузерную веб-игру, работающую под Apache (рабочий) и mod_perl. В пиковое время, когда сервер обрабатывает около 4200 запросов в минуту, каждые 3-15 минут или около того процесс Apache будет зависать.

Я установил, что эти процессы застряли в состоянии "FUTEX_WAIT" и, похоже, ничего не делают: они не потребляют ЦП или увеличивают объем ОЗУ. Но это серьезная проблема, потому что они просто сидят и занимают оперативную память.

Мое текущее решение - это задание cron, которое отбирает процессы Apache, застрявшие в futex_wait_queue_me. Но это не очень хорошо, потому что пользователи, которые ожидают ответа от зависших процессов Apache, получают ошибки (500: соединение с сервером закрыто без отправки данных обратно).

Мне не удалось воспроизвести проблему на моей машине для разработки, и я не могу понять, как приступить к устранению неполадок. Я хотел бы знать: как я могу диагностировать это дальше?

Редактировать : Я обнаружил, что проблема возникает после всплеска трафика, когда Apache порождает еще несколько рабочих процессов, а затем пытается отбросить их. Вот как это выглядит, когда работает нормально, с точки зрения ребенка:

$ sudo strace -p 21764
Process 21764 attached - interrupt to quit
read(5, "!", 1)                         = 1
tgkill(21764, 21791, SIGHUP)            = 0
tgkill(21764, 21791, SIG_0)             = 0
select(0, NULL, NULL, NULL, {0, 500000}) = ? ERESTARTNOHAND (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
rt_sigreturn(0xf)                       = -1 EINTR (Interrupted system call)
munmap(0x7f9905750000, 8392704)         = 0
munmap(0x7f98f8736000, 8392704)         = 0
[...]
madvise(0x7f98e4021000, 73728, MADV_DONTNEED) = 0
exit_group(0)                           = ?
Process 21764 detached

... но иногда это выглядит так:

$ sudo strace -p 24133
Process 24133 attached - interrupt to quit
read(5, "!", 1)                         = 1
tgkill(24133, 24164, SIGHUP)            = 0
tgkill(24133, 24164, SIG_0)             = 0
--- SIGTERM (Terminated) @ 0 (0) ---
rt_sigreturn(0xf)                       = 0
select(0, NULL, NULL, NULL, {0, 500000}) = 0 (Timeout)
tgkill(24133, 24140, SIGUSR1)           = 0
futex(0x7f9904f4e9d0, FUTEX_WAIT, 24140, NULL

... и дальше не идет.

Я не знаю, как отлаживать это дальше.

Ответы [ 2 ]

2 голосов
/ 10 января 2014

Это произошло из-за ошибки в mod-perl, так как исправлено, документировано здесь:

http://www.gossamer -threads.com / списки / ModPerl / DEV / 104026

1 голос
/ 15 октября 2011

выберите самое низкое время трафика и запустите apache с помощью strace на работающей машине, чтобы вы могли отследить причину ошибки, для одного интернет-блоггера решение сводилось к

rm /dev/random 
mknod -m 644 /dev/random c 1 9 

вы можете избежать 500: server closed connection without sending data back, используя обратную прокси-настройку, поэтому, когда apache обнаруживает таймаут без данных, он перенаправляет запрос другому дочернему модулю mod_perl

таким образом, вместо того, чтобы клиент получил 500, его запрос занимает дополнительные 5 секунд (не спрашивайте меня, как это сделать, см. руководство по mod_perl / apache:)

...