Understanding Unicorn and unicorn-worker-killer

原文:https://docs.gitlab.com/ee/administration/operations/unicorn.html

Understanding Unicorn and unicorn-worker-killer

注意:从 GitLab 13.0 开始,Puma 是基于 GitLab 多合一软件包的安装以及 GitLab Helm 图表部署中使用的默认 Web 服务器.

Unicorn

GitLab uses Unicorn, a pre-forking Ruby web server, to handle web requests (web browsers and Git HTTP clients). Unicorn is a daemon written in Ruby and C that can load and run a Ruby on Rails application; in our case the Rails application is GitLab Community Edition or GitLab Enterprise Edition.

Unicorn 具有多进程架构,可以更好地利用可用的 CPU 内核(进程可以在不同的内核上运行),并具有更强的容错能力(大多数故障仅隔离在一个进程中,无法完全关闭 GitLab). 启动时,Unicorn 的”主”进程使用 GitLab 应用程序代码加载一个干净的 Ruby 环境,然后生成继承此干净的初始环境的”工人”. “主人”从不处理任何留给工人的请求. 操作系统网络堆栈将传入的请求排队,并在工作进程之间分配它们.

在一个理想的世界中,主服务器将生成一个工人池,然后工人依次处理传入的 Web 请求,直到时间结束. 实际上,工作进程可能崩溃或超时:如果主服务器注意到工作时间过长,无法处理请求,它将以 SIGKILL(” kill -9”)终止工作进程. 无论工作进程如何结束,主进程都将再次用新的”干净”进程替换它. Unicorn 的设计宗旨是能够替换”崩溃的”工人,而无需放弃用户的要求.

这就是unicorn_stderr.log的 Unicorn worker 超时. 主过程具有下面的 PID 56227.

  1. [2015-06-05T10:58:08.660325 #56227] ERROR -- : worker=10 PID:53009 timeout (61s > 60s), killing
  2. [2015-06-05T10:58:08.699360 #56227] ERROR -- : reaped #<Process::Status: pid 53009 SIGKILL (signal 9)> worker=10
  3. [2015-06-05T10:58:08.708141 #62538] INFO -- : worker=10 spawned pid=62538
  4. [2015-06-05T10:58:08.708824 #62538] INFO -- : worker=10 ready

Tunable options

Unicorn 的主要可调选项是工作进程数和请求超时,之后 Unicorn 主服务器终止工作进程. 如果要调整这些设置,请参见Omnibus GitLab Unicorn 设置文档 .

unicorn-worker-killer

GitLab 内存泄漏. 这些内存泄漏在长时间运行的进程(例如 Unicorn 工作者)中表现出来. (不知道 Unicorn 主进程会泄漏内存,可能是因为它无法处理用户请求.)

为了使这些内存泄漏易于管理,GitLab 随附了unicorn-worker-killer gem . 每隔 16 个请求,这只宝石猴就会给独角兽工人打补丁以进行内存自检. 如果 Unicorn worker 的内存超过预设限制,则退出 worker 进程. 然后,Unicorn 主服务器自动替换工作进程.

这是处理内存泄漏的可靠方法:Unicorn 旨在处理”崩溃”的工作程序,因此不会丢弃任何用户请求. unicorn-worker-killer gem 被设计为仅在请求之间终止工作进程,因此不会影响用户请求. 您可以通过设置以下值/etc/gitlab/gitlab.rb来设置 Unicorn worker killer 的最小和最大内存阈值(以字节为单位):

  • 对于 GitLab 12.7及更高版本:

    1. unicorn['worker_memory_limit_min'] = "1024 * 1 << 20"
    2. unicorn['worker_memory_limit_max'] = "1280 * 1 << 20"
  • 对于 GitLab 12.6及更高版本:

    1. unicorn['worker_memory_limit_min'] = "400 * 1 << 20"
    2. unicorn['worker_memory_limit_max'] = "650 * 1 << 20"

否则,您可以设置GITLAB_UNICORN_MEMORY_MINGITLAB_UNICORN_MEMORY_MAX 环境变量 .

这就是 Unicorn_stderr.log 中的 Unicorn 工作程序内存重新启动的样子. 您看到工作程序 4(PID 125918)正在检查自己并决定退出. 内存阈值是 254802235 字节,大约 250MB. 对于 GitLab,此阈值是 200 到 250 MB 之间的随机值. 然后,主进程(PID 117565)接收工作进程,并生成具有 PID 127549 的新”工作进程 4”.

  1. [2015-06-05T12:07:41.828374 #125918] WARN -- : #<Unicorn::HttpServer:0x00000002734770>: worker (pid: 125918) exceeds memory limit (256413696 bytes > 254802235 bytes)
  2. [2015-06-05T12:07:41.828472 #125918] WARN -- : Unicorn::WorkerKiller send SIGQUIT (pid: 125918) alive: 23 sec (trial 1)
  3. [2015-06-05T12:07:42.025916 #117565] INFO -- : reaped #<Process::Status: pid 125918 exit 0> worker=4
  4. [2015-06-05T12:07:42.034527 #127549] INFO -- : worker=4 spawned pid=127549
  5. [2015-06-05T12:07:42.035217 #127549] INFO -- : worker=4 ready

从 GitLab.com 上摘录的另一段日志摘要是,” worker 4”仅在 23 秒内处理请求. 对于我们当前的 GitLab.com 设置和流量,这是正常值.

在某些 GitLab 网站上,独角兽内存重新启动的频率很高,可能会使管理员感到困惑. 通常他们是红鲱鱼 .