【问题标题】:Mongrel hangs with 100% CPU / EBADF (Bad file descriptor)Mongrel 以 100% CPU / EBADF 挂起(错误的文件描述符)
【发布时间】:2010-09-09 19:35:23
【问题描述】:

我们的服务器有 10 个运行 apache 的 mongrel_cluster 实例 在他们面前,不时有一个或一些人挂在上面。 在数据库中没有看到任何活动(我们正在使用 activerecord 会话)。 带有innodb 表的Mysql。 show innodb status 显示没有锁。显示 processlist 什么都不显示。

服务器是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 显示图像 / 来自数据库的图像 / 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 次),有人会断开连接等

发生这种情况时,mongrel-processes 不会占用任何大量内存,并且机器甚至没有交换,所以它可能不是内存泄漏。

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

【问题讨论】:

  • 您使用的是哪个版本的 Image Magick?

标签: ruby-on-rails ruby mongrel rmagick


【解决方案1】:

Deploying Rails Applications (A Step by Step Guide) 一书中的第 6.3 章很好地介绍了在 Linux 上安装和配置监控实用程序 Monit 并使用它来监控您的杂种。它可以在您的杂种动物失败时重新启动它们。

由于磁盘上存在重复的 PID 文件,旧版本的 Mongrel 无法重新启动。较新的版本支持 --clean 选项,该选项将删除剩余的 PID 文件(如果存在)。因此,您必须将 Mongrel 升级到支持 --clean 的版本才能解决过时的 PID 文件问题,仅 Monit 无法做到这一点。

【讨论】:

    【解决方案2】:

    考虑使用ImageScience,RMagick 会泄漏大量内存和锁定。

    【讨论】:

    • 替换 rmagick 并不是这个项目的真正选择。此外,除非它在生产中运行,否则我无法重现它,因此 rmagick 开发人员无法提供帮助(我尝试询问)。并且没有内存泄漏,只是锁定(可能是由于其他原因)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    相关资源
    最近更新 更多