Mongrel зависает со 100% CPU / EBADF (неверный файловый дескриптор)

У нас есть сервер с 10 запущенными экземплярами mongrel_cluster с apache перед ними, и время от времени один или несколько из них зависают. В базе данных не наблюдается никакой активности (мы используем сеансы ActiveRecord). Mysql с таблицами innodb. show innodb status показывает отсутствие блокировок. show processlist ничего не показывает.

Сервер линукс дебиан 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» дает в цикле для зависшего процесса mongrel следующее:

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

Я установил monit для мониторинга сервера. Пока нет автоматического перезапуска из-за проблемы с PID-файлом, но, возможно, я получу самую новую версию, которая поддерживает удаление устаревших PID-файлов. нужно перезагружать все время (~10 раз в день)

Процессы-монгрелы не занимают большого объема памяти, когда это происходит, и машина даже не выполняет подкачку, так что, вероятно, это не утечка памяти.

             total       used       free     shared    buffers     cached
Mem:       4152796    4083000      69796          0     616624    2613364
-/+ buffers/cache:     853012    3299784
Swap:      1999992         52    1999940

person Frontline    schedule 16.09.2008    source источник
comment
Какую версию Image Magick вы используете?   -  person Dave Cheney    schedule 17.09.2008


Ответы (2)


Рассмотрите возможность использования ImageScience. Известно, что RMagick допускает утечку больших объемов памяти и блокировки.

person manveru    schedule 17.09.2008
comment
Замена rmagick на самом деле не вариант для этого проекта. Кроме того, я не могу воспроизвести это, если оно не работает в производстве, поэтому разработчики rmagick не могут помочь (я пытался спросить). И утечки памяти нет, а только блокировка (может быть из-за чего-то другого) - person Frontline; 17.09.2008

В главе 6.3 книги Deploying Rails Applications (A Step by Step Guide) есть хороший раздел, посвященный установке и настройке утилиты мониторинга Monit в Linux и ее использованию для мониторинга ваших дворняжек. Он может перезапустить ваших дворняг, когда они терпят неудачу.

В старых версиях Mongrel возникали проблемы с перезапуском из-за дублирующегося файла PID, существующего на диске. В более новых версиях поддерживается параметр --clean, который удалит оставшиеся файлы PID, если они существуют. Таким образом, вам нужно обновить Mongrel до версии, которая поддерживает --clean, чтобы обойти проблему с устаревшим файлом PID, один только Monit не может этого сделать.

person sean lynch    schedule 16.09.2008