You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过systemd将所有浏览器进程归入自定义cgroup并设置内存限制(Ubuntu环境)

如何通过systemd将所有浏览器进程归入自定义cgroup并设置内存限制(Ubuntu环境)

我之前也遇到过类似的困扰——systemd接管cgroup后,确实没法像用cgmanager那样自由折腾了。不过好在systemd本身提供了完整的资源管控能力,下面是一套适配Ubuntu环境的解决方案,完全基于systemd原生工具,能自动把指定浏览器进程归入自定义cgroup,还能设置内存上限,而且尽量避免“漏网”的情况:

一、创建用户自定义Slice(核心配置)

首先我们要创建一个用户级的systemd slice,这就是我们的自定义cgroup,用来统一管控浏览器进程的资源。

  1. 在用户配置目录下创建slice文件:
mkdir -p ~/.config/systemd/user/
nano ~/.config/systemd/user/mybrowsers.slice
  1. 写入以下配置(根据你的需求修改内存限制数值):
[Unit]
Description=自定义浏览器进程组(带内存限制)

[Slice]
MemoryMax=4G  # 浏览器进程组的最大可用内存,比如设置为4GB
MemoryHigh=3.5G  # 可选:内存高水位线,超过后系统会主动回收内存,避免触发硬限制
  1. 重新加载用户级systemd配置,让新slice生效:
systemctl --user daemon-reload

二、为浏览器配置专属Systemd Service

接下来为每个浏览器创建用户级的service文件,强制它们启动时归入我们的自定义slice。

配置Firefox

创建~/.config/systemd/user/firefox.service

[Unit]
Description=Mozilla Firefox(归入自定义浏览器进程组)
Documentation=man:firefox(1)

[Service]
Type=exec
ExecStart=/usr/bin/firefox
Slice=mybrowsers.slice
# 可选:添加CPU限制,比如限制使用50%的CPU核心
CPUQuota=50%
Restart=on-failure

配置Chrome

创建~/.config/systemd/user/chrome.service

[Unit]
Description=Google Chrome(归入自定义浏览器进程组)
Documentation=man:chrome(1)

[Service]
Type=exec
ExecStart=/opt/google/chrome/chrome
Slice=mybrowsers.slice
MemoryMax=4G  # 也可以单独给Chrome设置不同的内存限制
Restart=on-failure
  1. 启用并启动这些服务:
systemctl --user enable --now firefox.service chrome.service

三、确保所有启动方式都纳入管控

直接调用浏览器二进制文件会绕开systemd service,所以我们要做两个小处理,避免“漏网”:

1. 命令行别名

在你的shell配置文件(比如~/.bashrc~/.zshrc)中添加别名,让命令行启动也走systemd service:

echo "alias firefox='systemctl --user start firefox'" >> ~/.bashrc
echo "alias chrome='systemctl --user start chrome'" >> ~/.bashrc

然后重新加载shell配置:

source ~/.bashrc

2. 修改桌面快捷方式

找到浏览器的桌面快捷方式文件(通常在~/.local/share/applications//usr/share/applications/),把Exec=行修改为通过systemd启动:
比如Firefox的.desktop文件,把原来的Exec=/usr/bin/firefox %u改成:

Exec=systemd-run --user --slice=mybrowsers.slice /usr/bin/firefox %u

这样不管是从桌面菜单启动,还是双击快捷方式,都会自动进入自定义slice。

四、验证配置有效性

配置完成后,我们可以检查是否生效:

  1. 启动浏览器,查看slice的状态:
systemctl --user status mybrowsers.slice

你应该能看到浏览器进程列在这个slice的下属进程中。
2. 查看内存限制是否正确应用:

cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/mybrowsers.slice/memory.max

输出的数值应该对应你设置的内存上限(比如4GB对应4294967296字节)。

五、备选方案:自动移动现有进程(无需修改启动方式)

如果你不想折腾启动方式的配置,也可以用一个轻量级的监控服务,自动把运行中的浏览器进程移到自定义slice里。虽然这属于轮询机制,但资源消耗极低,完全可以接受:

创建~/.config/systemd/user/browser-cgroup-monitor.service

[Unit]
Description=监控并自动移动浏览器进程到自定义slice

[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do for pid in $(pgrep -f "/usr/bin/firefox\|/opt/google/chrome/chrome"); do systemctl --user set-property $pid Slice=mybrowsers.slice 2>/dev/null; done; sleep 5; done'
Restart=always

[Install]
WantedBy=default.target

启用并启动这个监控服务:

systemctl --user enable --now browser-cgroup-monitor.service

它会每隔5秒检查一次浏览器进程,自动把它们归入自定义slice,不管你是怎么启动的浏览器。

备注:内容来源于stack exchange,提问作者Mikko Rantalainen

火山引擎 最新活动