# 扩展与自动扩展 Node.js 应用

Source: https://support.kapsulehost.com/zh-cn/site-scaling-and-autoscale

自动扩展功能会根据 CPU 负载的变化增加或减少运行您 Node.js 应用的实例数量，从而让繁忙时段获得更多容量，而在空闲时段降低成本。本指南将介绍 KPanel 中的相关标签页、每一项设置、计费方式，以及如何让应用安全地进行扩展。

## 扩展设置在 KPanel 中的位置

1. 登录 [KPanel](https://kpanel.kapsulehost.com)。
2. 点击左侧边栏中的**网站**，然后点击相应网站。
3. 在网站的左侧菜单中，打开**性能**，然后点击**扩展**。

直接访问地址为 `/websites/<site-id>/autoscale`。旧版地址 `/websites/<site-id>/scaling` 仍然有效，会跳转到同一位置。

![KPanel 中 Node.js 应用的自动扩展设置](https://support.kapsulehost.com/help/screenshots/site-scaling-and-autoscale.a7af79de.webp)

> **Note:** 该标签页仅出现在 Node.js 网站上。对于 WordPress、WooCommerce、静态网站、PHP、Python 或 Ruby 网站，该标签页不会出现在菜单中，因为此机制针对的是 Node.js 进程集群的扩展。

## 一个标签页，一套配置

KPanel 过去在这里设有两个标签页，**扩展**和**自动扩展**，对应同一套设置。它们其实是同一配置的两种视图，这种设计只会让人迷失方向，因此现在已合并为单一的**扩展**标签页：实时状态、设置项、最近的扩展事件，以及当前计费周期的用量与费用面板，全部集中在一处。

## 工作原理

您的应用以进程集群的形式运行。自动扩展功能会监测各运行实例的平均 CPU 使用率，并根据您设置的阈值增加或减少实例数量。

必须启用集群模式。如果您的应用尚未在集群模式下运行，启用自动扩展会自动为您切换到集群模式，这一过程会伴随短暂的重启。页面会在发生此情况时提示您。

## 查看实时状态

状态卡片会显示三项信息：

- **实例数**：当前正在运行的实例数量。
- **平均 CPU**：这些实例的平均 CPU 使用率。
- **集群**：应用是否处于集群模式。如果显示否，启用自动扩展将会切换此状态。

如果应用根本未在运行，卡片会直接说明这一点，而不是显示零值。

该标签页还会显示**最后的比例**，即最近一次扩展事件发生的时间，或显示**从未**。

## 各项设置

| 设置项 | 范围 | 它做什么 |
|---|---|---|
| 最小实例数 | 1 到 16 | 下限。扩展时不会低于此数值 |
| 最大实例数 | 1 到 16 | 上限。扩展时不会高于此数值 |
| CPU % 时扩展 | 5 到 99 | 平均 CPU 超过此值时增加一个实例 |
| CPU % 时缩减 | 1 到 95 | 平均 CPU 低于此值时减少一个实例 |
| 冷却时间（秒） | 30 到 3600 | 两次扩展操作之间的最短等待时间 |

主开关位于设置卡片标题中的切换按钮。关闭自动扩展时，设置项会变为灰色不可用，应用会保持当前的实例数量。

合理的起始值建议：

- **最小实例数设为 1 或 2。** 如果单个实例重启导致应用离线是您无法容忍的情况，请设为 2。
- **最大实例数**应设置为您愿意为峰值负载支付的数量，而非系统上限。
- **扩展阈值设在 70% 左右。** 足够高，可避免为用不到的冗余容量付费；也足够低，可在请求开始排队之前留出增加容量的时间。
- **缩减阈值设在 30% 左右。** 在两个阈值之间保留较大的间隔。
- **冷却时间设为几分钟。** 这是最容易被忽视的设置项。

> **Warning:** 将两个 CPU 阈值设置得过于接近会导致抖动：集群扩展后，由于负载随即分散到更多实例上，CPU 立即降至缩减阈值以下，于是又缩减，随后负载再次飙升，如此循环往复。请保持较大的阈值间隔，并设置充裕的冷却时间。抖动既浪费费用，也会使应用变得不稳定。

## 扩展事件

该标签页会按时间倒序列出最近的扩展事件，每条记录显示扩展方向、扩展前后的实例数量、触发该操作的 CPU 读数，以及发生时间。

当应用出现异常时，应查看此日志。短时间内出现多次上下波动的事件，说明您的阈值设置过于接近，或冷却时间过短。一次扩容后再也没有缩减，说明负载持续偏高，这属于容量问题而非配置问题。如果预期中应出现的事件完全没有记录，则说明 CPU 从未越过阈值，或自动扩展功能处于关闭状态。

## 自动扩展的费用

超出套餐基础配额的实例将按秒计量并计费。该标签页会显示当前计费周期内的以下信息：

- **实例时间已用**，以小时和分钟显示，下方附有原始的实例秒数。
- **目前已花费**，本周期内的花费金额。
- **预计月末用量**，根据目前的使用量推算得出。
- **跟踪情况**，在已记录的总量中，有多少使用窗口已完成计费。
- **周期进度**，本月已过去的天数占全月天数的比例。

每秒的计费费率显示在同一面板的顶部，因此您随时都能看到计费所依据的数值，与对应的用量并列显示。

> **Tip:** 预计月末用量是最值得关注的数字。它是根据目前为止的使用量推算得出的，因此若月初某一周异常繁忙，推算结果就会偏高。建议在几天后再查看一次，到月中再查看一次，之后再下结论。如果该数值高于您的预期，应降低最大实例数，而不是提高扩展阈值：实例数上限是硬性限制，而阈值只是一个参考提示。

将实例数缩减至最小值会停止计量计费。如果您完全关闭自动扩展，应用会保持当前的实例数量不变，因此如果关闭自动扩展是出于成本考虑，请先将实例数降至最小值。

## 让应用能够安全地扩展

该页面上有一条警告，也是其中最重要的一点：您的 Node.js 应用必须具备集群安全性，才能在多个实例之间顺利扩展。

实际上，这意味着：

**不要使用内存中的会话状态。** 如果已登录用户的会话保存在某个实例的内存中，那么一旦请求被路由到另一个实例，用户就会被登出。请将会话迁移到共享存储中。

**不要使用依赖其正确性的内存缓存。** 每个实例都有各自独立的内存。必须保持一致的缓存需要共享存储。

**不要写入本地文件系统并期望之后能读取回来。** 某个实例写入本地磁盘的上传内容，对其他实例是不可见的。请写入共享存储。

**不要使用无防护的定时任务。** 如果计时器在应用内部运行，那么每个实例都会运行它，这意味着在四个实例的情况下，一个夜间任务会运行四次。请将定时任务迁移到 cron 任务中，或为其添加锁机制。参见[定时任务](https://support.kapsulehost.com/zh-cn/cron-jobs)。

**不要假设实例数量是固定不变的。** 任何按实例索引分配工作的逻辑，一旦实例数量发生变化就会出现问题。

如果您的应用存在上述任何问题，请在启用自动扩展之前先予以修复。不具备集群安全性的应用会出现间歇性且难以复现的故障，因为这些故障取决于具体是哪个实例处理了哪个请求。

## 故障排查

**开关无法启用。** 启用此功能需要网站的写入权限。只读角色下，相关控件会被禁用。

**启用自动扩展后应用重启了。** 这是正常现象。切换到集群模式需要重启一次，且只会发生一次。

**用户会随机被登出。** 这是典型的非集群安全症状。会话保存在内存中，而请求被分发到了不同的实例上。

**实例数量上升后再也没有下降。** 可能是负载持续高于缩减阈值，也可能是有某些因素在独立于流量之外持续占用 CPU。请查看事件列表，了解应用实际在做什么。

**某个定时任务运行了多次。** 每个实例都运行了一次该任务。请将其迁移到 cron 任务，或添加锁机制。

**没有发生任何扩展。** 请确认开关已打开、应用正在运行，并且集群模式已启用。然后在事件列表中检查 CPU 是否确实越过了扩展阈值。

**费用高于预期。** 请在事件列表中查看是否存在抖动现象，然后降低最大实例数。

## 相关页面

- [网站性能与 APM](https://support.kapsulehost.com/zh-cn/site-performance)，用于确认 CPU 是否确实是瓶颈所在。
- [网站正常运行时间监控](https://support.kapsulehost.com/zh-cn/site-uptime-monitoring)，用于确认扩展确实提升了可用性。
- [定时任务](https://support.kapsulehost.com/zh-cn/cron-jobs)，适用于必须恰好运行一次的定时工作。
- [调整云服务器规格](https://support.kapsulehost.com/zh-cn/cloud-servers-resize)，适用于需要更大规格的机器而非更多实例的情况。
