Puma
Puma 是一个用于 Ruby 应用程序的简单、快速、多线程和高度并发的 HTTP 1.1 服务器。自 13.0 以来,它是默认的 GitLab Web 服务器,并已取代 Unicorn。从 14.0 开始,不再支持 Unicorn。
配置 Puma
要配置 puma:
- 确定合适的 Puma worker 和 thread 设置。
- 如果您要从 Unicorn 切换,将任何自定义设置转换为 Puma。
- 对于多节点部署,将负载均衡器配置为使用可读性检查。
-
重新配置极狐GitLab 使上述更改生效:
sudo gitlab-ctl reconfigure
对于基于 Helm 的部署,请参阅 webservice
chart 文档。
关于 Puma 配置的更多详细信息,请参阅 Puma 文档。
Puma Worker Killer
Puma fork worker 进程作为减少内存使用策略的一部分。
每次创建 worker 时,它都会与主进程共享内存,并且仅在对其内存页面进行更改或添加时才使用额外的内存。
因此,worker 使用的内存会随着时间的推移而增加,而 Puma Worker Killer 是恢复此内存的机制。
默认情况下:
- Puma Worker Killer 会在超过内存限制时重启一个 worker。
- Puma worker 的滚动重启每 12 小时执行一次。
要更改内存限制设置:
-
编辑
/etc/gitlab/gitlab.rb
:puma['per_worker_max_memory_mb'] = 1024
-
重新配置极狐GitLab 使更改生效:
sudo gitlab-ctl reconfigure
杀死和替换 worker 会产生相关成本,包括降低运行极狐GitLab 的能力,以及重新启动 worker 所消耗的 CPU。如果 worker killer 更换 worker 太频繁,per_worker_max_memory_mb
应该设置为更高的值。
worker 数量是根据 CPU 内核计算的,因此如果 worker 频繁重启,每分钟一次或多次,具有 4-8 名 worker 的小型部署可能会遇到性能问题,这太频繁了。
如果服务器有空闲内存,则更高的值 1200
或更多将是有益的。
Worker killer 每 20 秒检查一次,可以使用 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
值之前被杀死。 - 13.5 版本之前的公式,primary 的默认值是 550MB,
per_worker_max_memory_mb
为每个 worker 指定 850MB。 - 从 13.5 版本开始的值,primary:800MB,worker:1024MB。
-
worker 被杀死的阈值设置为限制的 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 秒超时。
puma['worker_timeout']
设置没有设置最大请求持续时间。要更改 worker 超时为 600 秒:
-
编辑
/etc/gitlab/gitlab.rb
:gitlab_rails['env'] = { 'GITLAB_RAILS_RACK_TIMEOUT' => 600 }
-
重新配置极狐GitLab 使更改生效:
sudo gitlab-ctl reconfigure
内存受限的环境
在可用 RAM 少于 4GB 的内存受限环境中,请考虑禁用 Puma 集群模式。
通过将 workers
的数量设置为 0
来配置 Puma 可以减少数百 MB 的内存使用量。有关 Puma worker 和 thread 设置的详细信息,请参阅 Puma 要求。
与默认设置的集群模式不同,只有一个 Puma 进程将为应用程序提供服务。
使用这种配置运行 Puma 的缺点是吞吐量降低,这可以被视为内存受限环境中的权衡。
在单节点模式下运行 Puma 时,不支持某些功能:
- 分阶段重启
- Puma Worker Killer
将 Unicorn 设置转换为 Puma
Puma 具有多线程架构,比 Unicorn 等多进程应用服务器使用更少的内存。大多数 Rails 应用程序请求通常包括一部分 I/O 等待时间。
在 I/O 等待期间,MRI Ruby 将 GVL(全局 VM 锁)释放给其他线程。因此,多线程 Puma 仍然可以处理比单个进程更多的请求。
切换到 Puma 时,由于两个应用程序服务器之间的差异,任何 Unicorn 服务器配置都 不会 自动转移。
下表总结了使用 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']
|
Puma exporter
您可以使用 Puma exporter 来衡量各种 Puma 指标。