Unicorn 内存使用几乎填满了所有 RAM

2024-03-16

这里本质上有3个问题:

1)Unicorn 似乎正在稳步填满所有 RAM,导致我手动删除工人。

2)独角兽似乎出于某种原因产生了额外的工人,尽管我已经指定了固定数量的工人(其中 7 个)。这在一定程度上导致了 RAM 的堆积,这也导致我手动删除工人。

3)就我而言,零停机部署是不可靠的。有时它会接受更改,有时我会遇到网关超时。每次部署都会变得非常紧张。

我真的不喜欢使用 Monit,因为它会在不等待工作人员完成其请求的情况下杀死工作人员。

那么,这正常吗?使用 Unicorn 进行部署的其他人是否也有同样的问题,即 RAM 无法控制地增长?

还有,在哪里产生的工人数量与定义的工人数量不匹配?

另一种选择是独角兽工人杀手,我会在阅读后尝试一下独角兽吃记忆 https://stackoverflow.com/questions/8306883/unicorn-eating-memory.

小更新:

所以到了 New Relic 告诉我记忆力几乎达到 95% 的地步。所以我不得不杀掉一个工人。有趣的是,杀死该工人会使内存下降很多,如下图所示。

那是怎么回事?

作为参考,这是我的unicorn.rb and unicorn_init.sh。希望有人告诉我某处有错误。

unicorn.rb

root = "/home/deployer/apps/myapp/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.stderr.log"
stdout_path "#{root}/log/unicorn.log"

listen "/tmp/unicorn.myapp.sock"
worker_processes 7
timeout 30

preload_app true

before_exec do |_|
  ENV["BUNDLE_GEMFILE"] = '/home/deployer/apps/myapp/current/Gemfile'
end

before_fork do |server, worker|
  # Disconnect since the database connection will not carry over
  if defined? ActiveRecord::Base
    ActiveRecord::Base.connection.disconnect!
  end

  old_pid = "#{root}/tmp/pids/unicorn.pid.oldbin`"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
  sleep 1
end

after_fork do |server, worker|
  # Start up the database connection again in the worker
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end

  Redis.current.quit
  Rails.cache.reconnect
end

unicorn_init.sh

#!/bin/sh
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/deployer/apps/myapp/current
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; BUNDLE_GEMFILE=/home/deployer/apps/myapp/current/Gemfile bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=deployer
set -u
OLD_PIN="$PID.oldbin"

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}

run () {
  if [ "$(id -un)" = "$AS_USER" ]; then
    eval $1
  else
    su -c "$1" - $AS_USER
  fi
}

case "$1" in
start)
  sig 0 && echo >&2 "Already running" && exit 0
  run "$CMD"
  ;;
stop)
  sig QUIT && exit 0
  echo >&2 "Not running"
  ;;
force-stop)
  sig TERM && exit 0
  echo >&2 "Not running"
  ;;
restart|reload)
  sig USR2 && echo reloaded OK && exit 0
  echo >&2 "Couldn't reload, starting '$CMD' instead"
  run "$CMD"
  ;;
upgrade)
  if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
  then
    n=$TIMEOUT
    while test -s $OLD_PIN && test $n -ge 0
    do
      printf '.' && sleep 1 && n=$(( $n - 1 ))
    done
    echo

    if test $n -lt 0 && test -s $OLD_PIN
    then
      echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
      exit 1
    fi
    exit 0
  fi
  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
  run "$CMD"
  ;;
reopen-logs)
  sig USR1
  ;;
*)
  echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
  exit 1
  ;;
esac

您似乎有两个问题:1)您在优雅重启的协调方面存在错误,导致旧的独角兽工人和旧主人留下来; 2)您的应用程序(不是独角兽)正在泄漏内存。

对于前者,看看你的before_fork代码,看来您正在使用内存约束方法示例配置 http://unicorn.bogomips.org/examples/unicorn.conf.rb但是,您在其中有一个错字.oldbin文件名(末尾有一个无关的反勾号),这意味着您永远不会向旧进程发出信号,因为您无法从不存在的文件中读取 pid。

对于后者,你必须进行调查和演练。在您的应用程序中查找随时间累积数据的缓存语义;仔细检查全局变量、类变量和类实例变量的所有使用,它们可以保留请求之间的数据引用。运行一些内存配置文件来表征您的内存使用情况。当工作线程的大小超过某个上限时,你可以通过杀死它们来减少内存泄漏;独角兽工人杀手 https://github.com/kzk/unicorn-worker-killer让这变得容易。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unicorn 内存使用几乎填满了所有 RAM 的相关文章

随机推荐

  • 将文本插入活动迷你缓冲区

    我试图在运行外部命令后将文本插入到迷你缓冲区中 例如 call interactively eval expression insert blah 当然 问题是 eval expression 在用户输入之前不会返回 我的最终目标是添加一些
  • Xcode 6:项目导航器中没有 Frameworks 文件夹

    我正在使用 Xcode 6 并遵循 Xcode 版本 4 教程 因此这里和那里的情况有所不同 我的项目导航器中似乎没有 Frameworks 文件夹 因此当我下载一些 framework 文件并在项目编辑器的构建阶段手动添加它们时 我没有
  • HttpUtility.UrlEncoded URL 段的错误请求 400

    因此 如果我的应用程序 MVC url 中存在 url 编码段 则 IIS 会抛出 BAD REQUEST 400 e g http u lasoo com au Offer http u lasoo com au Offer 9289 7
  • json 从遗留属性名称反序列化

    如何设置 Newtonsoft Json 使用旧成员名称反序列化对象 但使用当前成员名称序列化它 编辑 要求是从正在序列化 反序列化的类中删除过时的成员 这是一个需要序列化和反序列化的示例对象 我给了一个属性一个属性 其中包含它过去可能已序
  • 将字典转换为方阵

    我想学习如何将字典转换为方阵 根据我所读到的内容 我可能需要将其转换为 numpy 数组 然后重新调整它的形状 我不想使用 reshape 因为我希望能够根据用户输入的信息来执行此操作 换句话说 我希望代码能够给出一个方阵 无论用户输入了多
  • 必须重新验证此请求的标头错误吗?

    我注意到 Chrome 缓存了一个视频文件 我用服务器上的另一个替换了它 chrome 继续从缓存中提供旧的 使用 JW flash 播放器 5 请求的标头如下所示 joe joe desktop wget O S spider http
  • 为什么这个 MySQL 查询的结果会相互相乘?

    SELECT user id SUM COALESCE point points 0 AS total points SUM CASE WHEN point date gt this month THEN point points ELSE
  • 在 Flutter 中以编程方式扩展 ExpansionTile

    我只是想用ExpansionTile在 Flutter 中 我将示例修改为如下所示 我想隐藏箭头并使用Switch扩大瓷砖 可以吗 或者我是否需要以编程方式呈现子项的自定义小部件 基本上 我只需要显示 隐藏孩子们 这是我的代码 import
  • 如何在 bash 脚本中重新组织 sed 正则表达式中的嵌套引号,从而触发“未终止的替代模式”错误?

    以下命令抛出一个unterminated substitute patternbash 中的错误 eval echo sed s a u a z n n 1 但并不适合所有人 Linux 显然运行良好 Mac 抛出未终止的替代模式错误 我该
  • 骨干获取回调的正确方法

    我的 Backbone 应用程序有一个名为schedule 我对成功和错误调用正确函数的区别有点困惑 我尝试了下面列出的两种可能的方法 但我不知道有什么区别以及从放置的路由器调用函数的正确方法是什么在外部视图中 第一种方式 require
  • 使用OpenGL和GLFW的简单三角形[重复]

    这个问题在这里已经有答案了 我编写了一个小程序来使用顶点缓冲区显示一个简单的三角形 对于我使用 glfw 的窗口 我的环境是 Mac 10 9 XCode 5 窗口看起来是黑色的 但三角形不是油漆 这里是代码 include
  • 除应用内支付之外的 iOS 支付网关

    我有一个iPhone应用程序 其中有在线支付功能 对于付款 我想使用我自己的网站上的支付网关 这样我就可以将用户重定向到网站进行付款 谁能帮我 苹果会允许这个功能吗 任何帮助或建议将不胜感激 提前致谢 苹果允许第三方支付网关系统 Strip
  • java.lang.NoClassDefFoundError:无法初始化类 hudson.util.ProcessTree$UnixReflection

    我在尝试使用 Jenkins 构建项目时遇到了这个问题 java lang NoClassDefFoundError 无法初始化类 hudson util ProcessTree UnixReflection java lang NoCla
  • 使用 multer 和 gridfs 快速上传文件(文件损坏?)

    我正在尝试上传文件 图像 上传正常 文件存储在 Mongo 中 并且与原始文件具有相同的内容类型和大小 然后当我尝试下载它时 文件已损坏但保持相同的内容类型 如果我上传pdf 它会被识别为pdf 如果它是png 它也会被识别 但我无法打开它
  • 在 Web 服务器上部署可执行进程的最佳方法是什么?

    原问题 这个问题的标题可能措辞有点笨拙 但情况是这样的 我的服务器上部署了一个 NET Web 项目 它仍处于测试阶段 因此有很多发布和重新发布的情况发生 我还在同一个 VS 解决方案中编写了一个 C 可执行文件 称为 admin exe
  • Python 中的 DATEXII XML 文件到 DataFrame

    最近几天我一直在尝试打开并读取某个 XML 文件 DATEXII 格式 但到目前为止还没有成功 这是关于交通数据NDW 开放数据网站 http 83 247 110 3 OpenDataHistorie 荷兰道路和交通数据数据库 XML 文
  • 如何在大型对象上查找 Python Pickle 中的错误源

    我已经接管了某人的一个相当大的项目的代码 我正在尝试保存程序状态 并且有一个巨大的对象存储了几乎所有其他对象 我正在尝试腌制这个对象 但出现以下错误 pickle PicklingError 无法pickle 找不到它builtin mod
  • 再次使用该值作为索引以避免局部变量时列表交换两个元素失败

    l1 0 2 1 index 1 from ipdb import set trace set trace l1 index l1 l1 index l1 l1 index l1 index print l1 为什么会l1是相同的 l1 1
  • AngularJS:重复​​多个数组时防止显示最后一个分隔符

    Question 确保每行最后一个分隔符永远不会显示的最优雅的方法是什么 11 18 3 8 12 1 22 31 61 11 18 3 8 12 1 22 31 11 18 3 8 12 61 1 22 31 请注意 数据来自三个不同的数
  • Unicorn 内存使用几乎填满了所有 RAM

    这里本质上有3个问题 1 Unicorn 似乎正在稳步填满所有 RAM 导致我手动删除工人 2 独角兽似乎出于某种原因产生了额外的工人 尽管我已经指定了固定数量的工人 其中 7 个 这在一定程度上导致了 RAM 的堆积 这也导致我手动删除工