Sidekiq MemoryKiller

Rails 应用程序代码存在内存泄漏。对于 Web 请求,使用 puma-worker-killer 可以管理此问题,如果 Puma worker 超过内存限制,将重新启动它。Sidekiq MemoryKiller 将相同的方法应用于极狐GitLab 中处理后台作业的 Sidekiq 进程。

与 puma-worker-killer 不同,默认情况下为 13.0 及更高版本的所有极狐GitLab 安装实例启用,Sidekiq MemoryKiller 默认仅对 Omnibus 安装实例启用。

在默认设置下,MemoryKiller 会导致 Sidekiq 重启的频率不超过每 15 分钟一次,重启会导致传入后台作业延迟约一分钟。

一些后台作业依赖于长时间运行的外部进程。为确保在 Sidekiq 重新启动时完全终止这些进程,每个 Sidekiq 进程都应作为进程组 leader 运行(例如,使用 chpst -P)。如果使用 Omnibus 或安装了 runitbin/background_jobs 脚本,将为您处理。

配置 MemoryKiller

MemoryKiller 是使用环境变量控制的。

  • SIDEKIQ*daemon*MEMORY_KILLER:默认为 1。当设置为 0 时,MemoryKiller 工作在 legacy 模式。否则,MemoryKiller 在 daemon 模式下工作。

    legacy 模式中,MemoryKiller 在每次作业后检查 Sidekiq 进程 RSS(Resident Set Size)。

    daemon 模式中,MemoryKiller 每 3 秒检查一次 Sidekiq 进程的 RSS(由 SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL 定义)。

  • SIDEKIQ_MEMORY_KILLER_MAX_RSS(KB):如果设置了此变量,并且其值大于 0,则启用 MemoryKiller。否则将被禁用。

    SIDEKIQ_MEMORY_KILLER_MAX_RSS 定义 Sidekiq 进程允许的 RSS。

    legacy 模式中,如果 Sidekiq 进程超过允许的 RSS,则会触发不可逆的延迟优雅重启。Sidekiq 的重启发生在 SIDEKIQ_MEMORY_KILLER_GRACE_TIME 秒后。

    daemon 模式中,如果 Sidekiq 进程超过允许的 RSS 时间超过 SIDEKIQ_MEMORY_KILLER_GRACE_TIME,则会触发优雅重启。如果 Sidekiq 进程在 SIDEKIQ_MEMORY_KILLER_GRACE_TIME 内低于允许的 RSS,则中止重新启动。

    Omnibus 包的默认值设置在 Omnibus GitLab 仓库中

  • SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS(KB):在 daemon 模式下使用。如果 Sidekiq 进程 RSS(KB)超过 SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS,则会触发 Sidekiq 立即正常重启。

  • SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL:在 daemon 模式下使用,以定义检查进程RSS的频率,默认为 3 秒钟。

  • SIDEKIQ_MEMORY_KILLER_GRACE_TIME:默认为 900 秒(15 分钟)。 这个变量的使用被描述为 SIDEKIQ_MEMORY_KILLER_MAX_RSS 的一部分。

  • SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT:默认为 30 秒。这定义了所有 Sidekiq 作业允许完成的最长时间。 在此期间不接受任何新作业,并且一旦所有作业完成,该过程就会退出。

    如果在这段时间内作业没有完成,MemoryKiller 会通过向 Sidekiq 进程发送 SIGTERM 来中断所有当前正在运行的作业。

    如果 Sidekiq 没有执行进程硬关机/重启,Sidekiq 进程会在 Sidekiq.options[:timeout] + 2 秒后被强制终止。外部 supervisor(例如,runit)之后必须重新启动 Sidekiq。