# Understanding Unicorn and unicorn-worker-killer > 原文:[https://docs.gitlab.com/ee/administration/operations/unicorn.html](https://docs.gitlab.com/ee/administration/operations/unicorn.html) * [Unicorn](#unicorn) * [Tunable options](#tunable-options) * [unicorn-worker-killer](#unicorn-worker-killer) # Understanding Unicorn and unicorn-worker-killer[](#understanding-unicorn-and-unicorn-worker-killer "Permalink") **注意:**从 GitLab 13.0 开始,Puma 是基于 GitLab 多合一软件包的安装以及 GitLab Helm 图表部署中使用的默认 Web 服务器. ## Unicorn[](#unicorn "Permalink") GitLab uses [Unicorn](https://yhbt.net/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. ``` [2015-06-05T10:58:08.660325 #56227] ERROR -- : worker=10 PID:53009 timeout (61s > 60s), killing [2015-06-05T10:58:08.699360 #56227] ERROR -- : reaped # worker=10 [2015-06-05T10:58:08.708141 #62538] INFO -- : worker=10 spawned pid=62538 [2015-06-05T10:58:08.708824 #62538] INFO -- : worker=10 ready ``` ### Tunable options[](#tunable-options "Permalink") Unicorn 的主要可调选项是工作进程数和请求超时,之后 Unicorn 主服务器终止工作进程. 如果要调整这些设置,请参见[Omnibus GitLab Unicorn 设置文档](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.html) . ## unicorn-worker-killer[](#unicorn-worker-killer "Permalink") GitLab 内存泄漏. 这些内存泄漏在长时间运行的进程(例如 Unicorn 工作者)中表现出来. (不知道 Unicorn 主进程会泄漏内存,可能是因为它无法处理用户请求.) 为了使这些内存泄漏易于管理,GitLab 随附了[unicorn-worker-killer gem](https://github.com/kzk/unicorn-worker-killer) . 每隔 16 个请求,这只宝石[猴就会](https://en.wikipedia.org/wiki/Monkey_patch)给独角兽工人打[补丁](https://en.wikipedia.org/wiki/Monkey_patch)以进行内存自检. 如果 Unicorn worker 的内存超过预设限制,则退出 worker 进程. 然后,Unicorn 主服务器自动替换工作进程. 这是处理内存泄漏的可靠方法:Unicorn 旨在处理"崩溃"的工作程序,因此不会丢弃任何用户请求. unicorn-worker-killer gem 被设计为仅*在请求之间*终止工作进程,因此不会影响用户请求. 您可以通过设置以下值`/etc/gitlab/gitlab.rb`来设置 Unicorn worker killer 的最小和最大内存阈值(以字节为单位): * 对于 GitLab **12.7**及更高版本: ``` unicorn['worker_memory_limit_min'] = "1024 * 1 << 20" unicorn['worker_memory_limit_max'] = "1280 * 1 << 20" ``` * 对于 GitLab **12.6**及更高版本: ``` unicorn['worker_memory_limit_min'] = "400 * 1 << 20" unicorn['worker_memory_limit_max'] = "650 * 1 << 20" ``` 否则,您可以设置`GITLAB_UNICORN_MEMORY_MIN`和`GITLAB_UNICORN_MEMORY_MAX` [环境变量](../environment_variables.html) . 这就是 Unicorn_stderr.log 中的 Unicorn 工作程序内存重新启动的样子. 您看到工作程序 4(PID 125918)正在检查自己并决定退出. 内存阈值是 254802235 字节,大约 250MB. 对于 GitLab,此阈值是 200 到 250 MB 之间的随机值. 然后,主进程(PID 117565)接收工作进程,并生成具有 PID 127549 的新"工作进程 4". ``` [2015-06-05T12:07:41.828374 #125918] WARN -- : #: worker (pid: 125918) exceeds memory limit (256413696 bytes > 254802235 bytes) [2015-06-05T12:07:41.828472 #125918] WARN -- : Unicorn::WorkerKiller send SIGQUIT (pid: 125918) alive: 23 sec (trial 1) [2015-06-05T12:07:42.025916 #117565] INFO -- : reaped # worker=4 [2015-06-05T12:07:42.034527 #127549] INFO -- : worker=4 spawned pid=127549 [2015-06-05T12:07:42.035217 #127549] INFO -- : worker=4 ready ``` 从 GitLab.com 上摘录的另一段日志摘要是," worker 4"仅在 23 秒内处理请求. 对于我们当前的 GitLab.com 设置和流量,这是正常值. 在某些 GitLab 网站上,独角兽内存重新启动的频率很高,可能会使管理员感到困惑. 通常他们是[红鲱鱼](https://en.wikipedia.org/wiki/Red_herring) .