配置 GitLab 包内捆绑的 Puma 实例

Puma 是一个用于 Ruby 应用程序的快速、多线程和高度并发的 HTTP 1.1 服务器。它运行提供极狐GitLab 面向用户的功能的核心 Rails 应用程序。

减少内存使用

为了减少内存使用,Puma 派生 worker 进程。每次创建 worker 时,它都会与主进程共享内存。Worker 仅在更改或添加到其内存页面时才使用额外的内存。

内存使用会随着时间的推移而增加,但您可以使用 Puma Worker Killer 来恢复内存。

默认情况下:

更改内存限制设置

要更改内存限制设置:

  1. 编辑/etc/gitlab/gitlab.rb

    puma['per_worker_max_memory_mb'] = 1024
    
  2. 重新配置极狐GitLab:

    sudo gitlab-ctl reconfigure
    

当 worker 被 kill 和替换时,运行极狐GitLab 的能力会减少,并且会消耗 CPU。如果 Worker Killer 过于频繁地更换 worker,请将 per_worker_max_memory_mb 设置为更高的值。

Worker 计数是根据 CPU 内核计算的。如果 worker 过于频繁地重新启动(每分钟一次或更多次),具有 4-8 个 worker 的小型部署可能会遇到性能问题。

如果服务器有空闲内存,则 1200 或更高的值将是有益的。

监控 worker 内存

Worker Killer 每 20 秒检查一次内存。 要监视 Worker Killer ,请使用 Puma 日志 /var/log/gitlab/puma/puma stdout.log。 例如:

PumaWorkerKiller: Out of memory. 4 workers consuming total: 4871.23828125 MB
out of max: 4798.08 MB. Sending TERM to pid 26668 consuming 1001.00390625 MB.

根据以上输出:

  • 计算最大内存值的公式会导致 worker 在达到 per_worker_max_memory_mb 值之前被 kill。
  • 在 13.4 及更早版本中,公式的默认值是 primary 550MB,每个 worker 850MB。
  • 在 13.5 及更高版本中,值是 primary:800MB,worker:1024MB。
  • Worker 被 kill 的门槛设置为限制的 98%:

    0.98 * ( 800 + ( worker_processes * 1024MB ) )
    
  • 在上面的日志输出中,0.98 * ( 800 + ( 4 * 1024 ) ) 返回 max: 4798.08 MB 值。

例如,将最大值增加到 1200 会设置一个 max: 5488 MB 值。

Worker 在共享内存之上使用额外的内存。内存量取决于站点对极狐GitLab 的使用。

更改 worker 超时

默认 Puma 超时为 60 秒

notepuma['worker_timeout'] 没有设置最大请求持续时间。

要将 worker 超时更改为 600 秒:

  1. 编辑 /etc/gitlab/gitlab.rb

    gitlab_rails['env'] = {
       'GITLAB_RAILS_RACK_TIMEOUT' => 600
     }
    
  2. 重新配置极狐GitLab:

    sudo gitlab-ctl reconfigure
    

在内存受限的环境中禁用 Puma 集群模式

caution这是一个实验性的 Alpha 功能,如有更改,恕不另行通知。该功能尚未准备好用于生产用途。如果您想使用此功能,我们建议您先使用非生产数据进行测试。有关更多详细信息,请参阅 已知问题

在可用 RAM 少于 4GB 的内存受限环境中,请考虑禁用 Puma 集群模式

workers 的数量设置为 0 以减少数百 MB 的内存使用量:

  1. 编辑 /etc/gitlab/gitlab.rb

    puma['worker_processes'] = 0
    
  2. 重新配置极狐GitLab:

    sudo gitlab-ctl reconfigure
    

与默认设置的集群模式不同,只有一个 Puma 进程将为应用程序提供服务。 有关 Puma worker 和线程设置的详细信息,请参阅 Puma 要求

在这种配置中运行 Puma 的缺点是吞吐量降低,这在内存受限的环境中可以被认为是公平的权衡。

请记住有足够的可用交换空间以避免内存不足 (OOM) 情况。 查看内存要求,了解详细信息。

Puma 单一模式已知问题

在单一模式下运行 Puma 时,不支持某些功能:

  • 分阶段重启
  • Puma Worker Killer

将 Puma 与 Rugged 一起使用时的性能警告

对于使用 NFS 存储 Git 仓库的部署,极狐GitLab 通过 Rugged 使用直接 Git 访问来提高性能。

如果直接 Git 访问可用并且 Puma 正在单线程运行,则会自动启用 Rugged 的使用,除非它被功能标志禁用。

MRI Ruby 使用全局 VM 锁 (GVL)。 GVL 允许 MRI Ruby 是多线程的,但最多只能在单个内核上运行。

Git 包括密集的 I/O 操作。当 Rugged 长时间使用一个线程时,可能正在处理请求的其他线程可能会饿死。在单线程模式下运行的 Puma 没有这个问题,因为最多同时处理一个请求。

目前正在努力移除 Rugged 的使用。尽管目前没有 Rugged 的性能是可以接受的,但在某些情况下,使用它运行可能仍然有益。

鉴于使用多线程 Puma 运行 Rugged 的警告以及 Gitaly 可接受的性能,如果使用 Puma 多线程(当 Puma 配置为使用多个线程运行时),我们将禁用 Rugged 使用。

在某些情况下,此默认行为可能不是最佳配置。如果 Rugged 在您的部署中发挥重要作用,我们建议您进行基准测试以找到最佳配置:

  • 最安全的选择是从单线程 Puma 开始。
  • 要强制 Rugged 与多线程 Puma 一起使用,您可以使用功能标志。

将 Puma 配置为通过 SSL 侦听

Puma 与 Omnibus GitLab 一起部署时,默认通过 Unix 套接字进行侦听。要将 Puma 配置为通过 HTTPS 端口进行侦听,请按照以下步骤操作:

  1. 为 Puma 侦听的地址生成 SSL 证书密钥对。在下面的示例中是 127.0.0.1

    note如果使用来自自定义证书颁发机构 (CA) 的自签名证书,请按照文档使它们受到其他极狐GitLab 组件的信任。
  2. 编辑 /etc/gitlab/gitlab.rb

    puma['ssl_listen'] = '127.0.0.1'
    puma['ssl_port'] = 9111
    puma['ssl_certificate'] = '<path_to_certificate>'
    puma['ssl_certificate_key'] = '<path_to_key>'
    
    # Disable UNIX socket
    puma['socket'] = ""
    
  3. 重新配置极狐GitLab:

    sudo gitlab-ctl reconfigure
    
note除了 Unix 套接字,Puma 还在端口 8080 上侦听 HTTP,提供要被 Prometheus 抓取的指标。目前不可能让 Prometheus 通过 HTTPS 抓取它们。因此,从技术上讲,在不丢失 Prometheus 指标的情况下关闭此 HTTP 侦听器是不可能的。

从 Unicorn 切换到 Puma

note对于基于 Helm 的部署,请参阅 webservice chart 文档

从 13.0 版本开始,Puma 是默认的 Web 服务器,并且 Unicorn 已被禁用。 在 14.0 版本中,Unicorn 已从 Linux 包中删除,不再受支持。

Puma 采用多线程架构,与 Unicorn 等多进程应用服务器相比,它使用的内存更少。大多数 Rails 应用程序请求通常包含一定比例的 I/O 等待时间。

在 I/O 等待期间,MRI Ruby 将 GVL 释放给其它线程。因此,多线程 Puma 仍然可以处理比单个进程更多的请求。

当切换到 Puma 时,由于两个应用程序服务器之间的差异,任何 Unicorn 服务器配置都不会自动继承。

从 Unicorn 切换到 Puma:

  1. 确定合适的 Puma worker 和 thread 设置
  2. /etc/gitlab/gitlab.rb 中,将任何自定义 Unicorn 设置转换为 Puma。

    下表总结了在使用 Linux 包时,哪些 Unicorn 配置键与 Puma 中的配置键对应,哪些没有对应的配置键。

    Unicorn Puma
    unicorn['enable'] puma['enable']
    unicorn['worker_timeout'] puma['worker_timeout']
    unicorn['worker_processes'] puma['worker_processes']
    n/a puma['ha']
    n/a puma['min_threads']
    n/a puma['max_threads']
    unicorn['listen'] puma['listen']
    unicorn['port'] puma['port']
    unicorn['socket'] puma['socket']
    unicorn['pidfile'] puma['pidfile']
    unicorn['tcp_nopush'] n/a
    unicorn['backlog_socket'] n/a
    unicorn['somaxconn'] puma['somaxconn']
    n/a puma['state_path']
    unicorn['log_directory'] puma['log_directory']
    unicorn['worker_memory_limit_min'] n/a
    unicorn['worker_memory_limit_max'] puma['per_worker_max_memory_mb']
    unicorn['exporter_enabled'] puma['exporter_enabled']
    unicorn['exporter_address'] puma['exporter_address']
    unicorn['exporter_port'] puma['exporter_port']
  3. 重新配置极狐GitLab:

    sudo gitlab-ctl reconfigure
    
  4. (可选)对于多节点部署,将负载均衡器配置为使用 readiness check。