Mongrel зависает со 100% CPU / EBADF (плохой дескриптор файла)
У нас есть сервер с 10 запущенными экземплярами mongrel_cluster с apache перед ними, и время от времени один или несколько из них зависают. В базе данных нет активности (мы используем сеансы activerecord). Mysql с таблицами innodb. Показывать статус innodb не показывает никаких блокировок. Показать список процессов ничего не показывает.
Сервер Linux Debian 4.0
Ruby - это: ruby 1.8.6 (2008-03-03 patchlevel 114) [i486-linux]
Rails это: Rails 1.1.2 (да, довольно старый)
Мы используем родной соединитель mysql (gem install mysql)
"strace -p PID" дает в цикле для процесса зависания шавки следующее:
gettimeofday({1219834026, 235289}, NULL) = 0
select(4, [3], [0], [], {0, 905241}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 235477}, NULL) = 0
select(4, [3], [0], [], {0, 905053}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 235654}, NULL) = 0
select(4, [3], [0], [], {0, 904875}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 235829}, NULL) = 0
select(4, [3], [0], [], {0, 904700}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 236017}, NULL) = 0
select(4, [3], [0], [], {0, 904513}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 236192}, NULL) = 0
select(4, [3], [0], [], {0, 904338}) = -1 EBADF (Bad file descriptor)
gettimeofday({1219834026, 236367}, NULL) = 0
...
Я использовал lsof и обнаружил, что процесс использует 67 файловых дескрипторов (lsof -p PID |wc -l)
Есть ли другой способ отладки, чтобы я мог, например, определить, какой дескриптор файла "плохой"? Любая другая информация или предложения? Кто-нибудь еще видел это?
Сайт используется достаточно, но не слишком, средняя нагрузка обычно составляет около 0,3.
Некоторая дополнительная информация Я установил mongrelproctitle, чтобы показать, что делали зависшие процессы, и кажется, что они зависают в методе, который отображает изображения, используя file_column / images из базы данных / rmagick, чтобы изменить размер и сделать изображения серыми.
Не окончательная проблема здесь, но это подозрение. Есть ли что-то явно не так со следующим? Метод отображает статическое изображение, если заказ не содержит изображения, в противном случае изображение изменяется из заказа. Кеша такова, что изображение обновляется в браузере каждый раз. Изображение вставляется на страницу с обычным тегом изображения.
код:
def preview_image
@order = session[:order]
if @order.image.nil?
@headers['Pragma'] = 'no-cache'
@headers['Cache-Control'] = 'no-cache, must-revalidate'
send_data(EMPTY_PIC.to_blob, :filename => "img.jpg", :type =>
"image/jpeg", :disposition => "inline")
else
@pic = Image.read(@order.image)[0]
if (@order.crop)
@pic.crop!(@order.crop[:x1].to_i, @order.crop[:y1].to_i,
@order.crop[:width].to_i, @order.crop[:height].to_i, true)
end
@pic.resize!(103,130)
@pic = @pic.quantize(256, Magick::GRAYColorspace)
@headers['Pragma'] = 'no-cache'
@headers['Cache-Control'] = 'no-cache, must-revalidate'
send_data(@pic.to_blob, :filename => "img.jpg", :type =>
"image/jpeg", :disposition => "inline")
end
end
Вот вывод lsof, если кто-то может найти какие-либо проблемы в нем. Не знаю, как оно будет форматироваться в этом сообщении...
lsof: WARNING: can't stat() ext3 file system /dev/.static/dev
Output information may be incomplete.
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
mongrel_r 11628 username cwd DIR 9,2 4096 1870688
/home/domains/example.com/usernameOrder/releases/20080831121802
mongrel_r 11628 username rtd DIR 9,1 4096 2 /
mongrel_r 11628 username txt REG 9,1 3564 167172
/usr/bin/ruby1.8
mongrel_r 11628 username mem REG 0,0 0
[heap] (stat: No such file or directory)
mongrel_r 11628 username DEL REG 0,8 15560245
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560242
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560602
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560601
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560684
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560683
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560685
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560568
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560607
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560569
/dev/zero
mongrel_r 11628 username mem REG 9,1 1933648 456972
/usr/lib/libmysqlclient.so.15.0.0
mongrel_r 11628 username DEL REG 0,8 15442414
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560546
/dev/zero
mongrel_r 11628 username mem REG 9,1 67408 457393
/lib/i686/cmov/libresolv-2.7.so
mongrel_r 11628 username mem REG 9,1 17884 457386
/lib/i686/cmov/libnss_dns-2.7.so
mongrel_r 11628 username DEL REG 0,8 15560541
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560246
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560693
/dev/zero
mongrel_r 11628 username DEL REG 0,8 15560608
/dev/zero
mongrel_r 11628 username mem REG 9,1 25700 164963
/usr/lib/gconv/gconv-modules.cache
mongrel_r 11628 username mem REG 9,1 83708 457384
/lib/i686/cmov/libnsl-2.7.so
mongrel_r 11628 username mem REG 9,1 140602 506903
/var/lib/gems/1.8/gems/mysql-2.7/lib/mysql.so
mongrel_r 11628 username mem REG 9,1 1282816 180935
...
mongrel_r 11628 username 1w REG 9,2 462923 1575329
/home/domains/example.com/usernameOrder/shared/log/mongrel.8001.log
mongrel_r 11628 username 2w REG 9,2 462923 1575329
/home/domains/example.com/usernameOrder/shared/log/mongrel.8001.log
mongrel_r 11628 username 3u IPv4 15442350 TCP
localhost:8001 (LISTEN)
mongrel_r 11628 username 4w REG 9,2 118943548 1575355
/home/domains/example.com/usernameOrder/shared/log/production.log
mongrel_r 11628 username 5u REG 9,1 145306 234226
/tmp/mongrel.11628.0 (deleted)
mongrel_r 11628 username 7u unix 0xc3c12480 15442417
socket
mongrel_r 11628 username 11u REG 9,1 50 234180
/tmp/CGI.11628.2
mongrel_r 11628 username 12u REG 9,1 26228 234227
/tmp/CGI.11628.3
Я установил монитор для мониторинга сервера. Нет автоматического перезапуска из-за проблемы с файлом PID, но, возможно, я получу самую новую версию, которая поддерживает удаление устаревших файлов PID.
Было бы неплохо, хотя бы на самом деле решить проблему, потому что кто-то получит отключение и т. Д., Если сервер нужно будет перезагружать все время (~10 раз в день)
Процессы mongrel не занимают большого объема памяти, когда это происходит, и машина даже не обменивается, так что, вероятно, это не утечка памяти.
total used free shared buffers cached
Mem: 4152796 4083000 69796 0 616624 2613364
-/+ buffers/cache: 853012 3299784
Swap: 1999992 52 1999940
2 ответа
Подумайте об использовании ImageScience, известно, что RMagick теряет огромные объемы памяти и блокирует.
Глава 6.3 в книге "Развертывание Rails-приложений" (пошаговое руководство) содержит хороший раздел, посвященный установке и настройке утилиты мониторинга Monit в Linux и ее использованию для мониторинга ваших ублюдков. Это может перезапустить ваши дворняги, когда они терпят неудачу.
В старых версиях Mongrel возникли проблемы с повторным запуском из-за дублирования файла PID, существующего на диске. Более новые версии поддерживают опцию --clean, которая избавит от оставшихся файлов PID, если они существуют. Таким образом, вам нужно обновить Mongrel до версии, которая поддерживает --clean, чтобы обойти устаревшую проблему с PID-файлом. Только Monit не может этого сделать.