Mongrel挂在100%CPU / EBADF上(错误的文件描述符)
我们有一台服务器,其中有10个运行apache的mongrel_cluster实例
在他们面前,时不时地挂着一个或者几个。
在数据库中看不到任何活动(我们正在使用activerecord会话)。
带有innodb表的mysql。 show innodb status不显示任何锁定。展示
进程列表什么也没显示。
服务器是Linux debian 4.0
Ruby是:ruby 1.8.6(2008-03-03补丁程序级别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显示图像/来自数据库的图像/
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
解决方案
回答
《部署Rails应用程序》(循序渐进的指南)一书中的6.3章很好地介绍了在Linux上安装和配置Monitoring Utility Monit以及使用它来监视mongrels。当它们出现故障时,它可以重新启动它们。
由于磁盘上存在重复的PID文件,因此较早版本的Mongrel无法重新启动。较新的版本支持--clean选项,该选项将清除剩余的PID文件(如果存在)。因此,我们必须将Mongrel升级到支持--clean的版本,以解决过时的PID文件问题,仅Monit无法做到这一点。
回答
考虑使用ImageScience,众所周知RMagick会泄漏大量内存并锁定。