# 16.14.资源限制

在 FreeBSD 中，资源限制是控制和管理系统资源分配给进程和用户的机制。这些限制旨在防止单个进程或用户消耗过多资源，从而导致性能下降或系统不稳定。资源限制有助于确保系统中所有活动进程和用户之间的资源公平分配。

FreeBSD 提供了几种方法供管理员限制个体使用的系统资源量。

传统方法通过编辑 **/etc/login.conf** 来定义登录类。虽然这种方法仍然受支持，但任何更改都需要多步过程：编辑此文件、重建资源数据库、对 **/etc/master.passwd** 进行必要更改，并重建密码数据库。根据需要配置的用户数量，这可能会变得耗时。

[rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 提供了一种更精细的方法来控制资源限制。此命令不仅支持用户限制，还可以用于为进程和 Jail 设置资源约束。

本节展示了两种控制资源的方法，从传统方法开始。

## 16.14.1. 资源类型

FreeBSD 提供了多种类型资源的限制，包括：

**表 1. 资源类型**

| 类型     | 描述                   |
| ------ | -------------------- |
| CPU 时间 | 限制进程可消耗的 CPU 时间量     |
| 内存     | 控制进程可以使用的物理内存量       |
| 打开的文件  | 限制进程可以同时打开的文件数量      |
| 进程数    | 控制用户或进程可以创建的进程数量     |
| 文件大小   | 限制进程可以创建的文件的最大大小     |
| 核心转储   | 控制是否允许进程生成核心转储文件     |
| 网络资源   | 限制进程可以使用的网络资源（例如套接字） |

有关完整的资源类型列表，请参阅 [login.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=login.conf\&sektion=5\&format=html) 和 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html)。

## 16.14.2. 配置登录类

在传统方法中，登录类及应用于登录类的资源限制定义在 **/etc/login.conf** 中。每个用户账户可以分配给一个登录类，`default` 是默认的登录类。每个登录类都有一组关联的登录能力。登录能力是一个 `name=value` 的对，其中 *name* 是一个已知的标识符，*value* 是一个任意字符串，根据 *name* 的不同，*value* 会被相应地处理。

配置资源限制的第一步是通过执行以下命令打开 **/etc/login.conf** 文件：

```sh
# ee /etc/login.conf
```

然后找到要修改的用户类部分。在这个示例中，假设用户类名为 `limited`，如果它不存在，可以创建它：

```ini
limited:\ ①
        :maxproc=50:\ ②
        :tc=default: ③
```

* ① 用户类的名称。
* ② 为 `limited` 类中的用户设置最大进程数 (maxproc) 为 50。
* ③ 表示此用户类继承自 "default" 类的默认设置。

修改 **/etc/login.conf** 文件后，运行 [cap\_mkdb(1)](https://man.freebsd.org/cgi/man.cgi?query=cap_mkdb\&sektion=1\&format=html) 生成 FreeBSD 用来应用这些设置的数据库：

```sh
# cap_mkdb /etc/login.conf
```

可以使用 [chpass(1)](https://man.freebsd.org/cgi/man.cgi?query=chpass\&sektion=1\&format=html) 命令更改用户的类，执行以下命令：

```sh
# chpass username
```

这将打开一个文本编辑器，在那里添加新的 `limited` 类，如下所示：

```ini
# 修改 username 的用户信息数据库
Login: username
Password: $6$2H.419USdGaiJeqK$6kgcTnDadasdasd3YnlNZsOni5AMymibkAfRCPirc7ZFjjv
DVsKyXx26daabdfqSdasdsmL/ZMUpdHiO0
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:
Expire [month day year]:
Class: limited
Home directory: /home/username
Shell: /bin/sh
Full Name: User &
Office Location:
Office Phone:
Home Phone:
Other information:
```

现在，分配给 `limited` 类的用户将具有最多 50 个进程的限制。请记住，这只是通过 **/etc/login.conf** 文件设置资源限制的一个示例。

请注意，在对 **/etc/login.conf** 文件进行更改后，用户需要注销并重新登录才能使更改生效。此外，在编辑系统配置文件时，尤其是使用特权访问时，请始终小心。

## 16.14.3. 启用和配置资源限制

[rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 系统提供了一种更精细化的方式来为单个进程和用户设置和管理资源限制。它允许你动态地为特定进程或用户分配资源限制，无论它们属于哪个用户类。

使用 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 的第一步是通过将以下行添加到 **/boot/loader.conf** 并重新启动系统来启用它：

```sh
kern.racct.enable=1
```

然后，通过执行以下命令启用并启动 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 服务：

```sh
# sysrc rctl_enable="YES"
# service rctl start
```

然后可以使用 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 来设置系统规则。

规则语法（[rctl.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=rctl.conf\&sektion=5\&format=html)）通过使用主体、主体 ID、资源和动作来控制，如下所示的示例规则：

```ini
subject:subject-id:resource:action=amount/per
```

例如，要限制用户最多只能添加 10 个进程，可以执行以下命令：

```sh
# rctl -a user:username:maxproc:deny=10/user
```

要检查应用的资源限制，可以执行 [rctl(8)](https://man.freebsd.org/cgi/man.cgi?query=rctl\&sektion=8\&format=html) 命令：

```sh
# rctl
```

输出应该类似于以下内容：

```ini
user:username:maxproc:deny=10
```

如果规则已添加到 **/etc/rctl.conf** 文件中，则这些规则将在重启后继续生效。其格式为规则，前面不带命令。例如，前述规则可以添加为：

```ini
user:username:maxproc:deny=10
```
