Smail/docs/生产资源部署说明.md
smail 46a767c8d9
Some checks are pending
Security Checks / security (push) Waiting to run
部署Nginx反代与可信证书并补充远程验收和续期保护
2026-09-17 23:01:35 +08:00

105 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 生产资源部署说明
## 状态与边界
### 2026 年 9 月 17 日 22:02 清理后更新
本节优先于后续 21:51 失败快照。主机 `/tmp` 为 tmpfs,6 项历史发布临时文件占用约 355.5 MiB;已确认无活动进程引用,将完整内容归档到 `/var/backups/host-tmp-archive-20260917T215952` 所在 ext4 磁盘,核验摘要和元数据后以符号链接保留原访问路径。没有清空数据库、停用其他服务、创建交换空间、清除内核缓存或降低预算。
清理后按原 `--reserve-mib 128` 连续执行 5 次预检,间隔 15 秒,均退出 0。主机可用内存约 625 至 643 MiB,最小的“可用内存减 Smail 剩余增长”约 159 MiB,高于 128 MiB 门槛约 31 MiB。Smail PID 始终为 571735,OOM 计数为零;`/tmp` 实际占用降至 610,304 字节。
这仅解除即时资源快照阻塞,不代表硬上限可在同机服务任意增长时得到保障。生产容量与持续监控仍未通过。大体积构建及验收产物应显式落在磁盘上的项目专用 `/var/tmp` 目录;原 `/tmp` 链接仅为兼容历史访问,不是新的长期部署入口。完整逐文件清单和预检结果保存在该归档目录,访问权限为 root 专用。
### 2026 年 9 月 17 日 21:51 更新
以下早期“尚未远程执行”的描述已由本次证据更新:模板已部署,资源反例 15 项及 Node 入口已在 47 服务器通过;主服务通过新增 `/etc/systemd/system/smail.service.d/20-go-memory.conf` 设置 `Environment=GOMEMLIMIT=256MiB`,进程环境解析确认生效。原 `/etc/smail/smail.env` 未改动,仍为 `root:root`、`0600`;高水位、硬上限和系统保留预算未降低。
整改前资源预检的两项失败是缺少有效 Go 内存目标及主机余量不足;整改后仅剩主机余量不足。21:51 快照:可用内存 326,848,512 字节,服务当前控制组占用 18,100,224 字节,增长到 536,870,912 字节硬上限还需 518,770,688 字节,另需保留 134,217,728 字节。单次快照不能保障同机 MySQL、PostgreSQL、Scert 后续增长,不能据此宣布容量已通过。
停服备份位于 `/var/backups/smail-memory-20260917-2155`,归档已校验可读。配置回退应在维护窗口恢复已备份配置并停用本轮新增 drop-in,经 `daemon-reload`、重启及运行进程预检确认;不得自动删除备份或放宽硬限额。未触碰其他项目配置或数据。
完整远程记录位于 `/var/tmp/smail-review-acceptance-20260917-2140`。`resource-before.json` 与 `resource-after.json` 均为不通过证据,后一份对应工具退出码 1;`resource-tests-retry.log` 为测试通过证据。这些结果仍不等于生产批准。
本说明对应 2026 年 9 月 17 日的共享主机资源整改。以下配置和检查工具是待远程验收的候选变更,不表示已经部署到 47 服务器,也不是生产容量承诺。
- [x] 增加主服务资源上限、OOM 收尾与重启频率限制,等待远程复审。
- [x] 增加只读资源预检和失败反例测试,等待远程执行。
- [!] 当前会话没有可用的 47 服务器 SSH 登录凭据,无法取得实时资源快照或部署。
- [ ] 明确同机 MySQL、Scert、操作系统的增长预算,选择 Smail 的实际限额。
- [ ] 清空隔离验收实例的全部项目数据库,部署最新产物,执行安装、恢复、队列和内部 25 端口验收。
- [ ] 记录峰值、持续运行、过载恢复和监控告警,完成资源项复审。
不要停止其他项目以通过测试,不自动扩充内存限额,不创建交换文件,不把旧记录中的可用内存当作当前资源。数据库清理只涉及获准的 Smail 测试实例,执行前必须备份并确认全部数据库的归属。
## 候选默认预算
正式安装模板新增如下配置,部署人员需要先核算宿主机预算。默认值不是根据完整生产负载测得的安全容量。
| 配置 | 候选默认值 | 用途 |
| --- | --- | --- |
| `GOMEMLIMIT` | `256MiB` | 新建环境文件中的 Go 回收目标,不是进程硬上限 |
| `MemoryHigh` | `384M` | 控制组内存高水位 |
| `MemoryMax` | `512M` | 主服务及同组子进程的内存硬上限 |
| `MemorySwapMax` | `0` | 不以交换空间掩盖内存不足 |
| `CPUQuota` | `100%` | 默认最多使用一个 CPU 的时间配额,不是整机所有 CPU |
| `TasksMax` | `256` | 限制同组进程及线程数量,不等同于邮件用户数 |
| `OOMPolicy` / `KillMode` | `stop` / `control-group` | OOM 或停止时收尾整个服务进程组 |
| `Restart` / `RestartSec` | `on-failure` / `10s` | 故障后退避重启 |
| `StartLimitIntervalSec` / `StartLimitBurst` | `300s` / `3` | 五分钟内最多三次启动,防止持续重启占用主机资源 |
| `TimeoutStopSec` | `90s` | 覆盖队列 25 秒、数据库 35 秒及其他服务收尾时间 |
已有 `/etc/smail/smail.env` 始终保留,不自动添加或改写已有 `GOMEMLIMIT`。维护人员应在停服备份后人工检查该文件,保持 `root:root`、`0600` 权限。不要将整个环境文件输出到日志、聊天或验收文档。
若已有本机 systemd drop-in,它可能覆盖仓库模板。不能只看文件内容或 `daemon-reload` 成功;必须核对运行进程、服务管理器和内核控制组的实际值。
## 只读预检
工具只在 Linux 部署主机检查正在运行的 `smail.service`,要求 root、Python 3 和 cgroup v2。不会启动程序、改配置、重启服务、读写数据库或进行压测。
在服务器的本次审查源码目录运行:
```sh
python3 deploy/check_resources.py --reserve-mib 256
```
`256` 只是命令示例,必须按同机服务的增长及系统开销核算。工具要求显式指定且不得小于 `128`,不能为了通过检查降低已确定的预算。
预检逐项核对:
1. 服务处于运行状态,主 PID 位于本服务独立的统一控制组。
2. 内存高水位、硬上限、交换与任务数的 systemd 属性和实际内核值相符,CPU 配额有限。
3. 进程设置了有效的 `GOMEMLIMIT`,低于内存高水位,当前内存未达到高水位。
4. 从当前占用增长到 `MemoryMax` 后,主机仍有指定的保留内存;同时检查上级控制组的内存、任务数和 CPU 约束。
5. OOM 收尾、整个进程组停止、至少 90 秒且有界的停止期限、重启退避和启动频率限制有效,当前控制组没有累计 OOM 或 OOM kill。
6. 取证前后 PID、调用标识和所查服务属性一致,避免把重启前后的数据拼成通过证据。
工具仅从进程环境解析 `GOMEMLIMIT` 的数值,不输出其他环境项。报告中 `resource_checks_passed=true` 只表示这一次快照通过资源规则,`production_approved` 始终是 `false`;退出码 `0` 不构成完整生产放行。取证失败、权限不足、cgroup v1、属性缺失或检查不通过时返回非零。
主机资源随其他服务负载变化。瞬时检查没有为 Smail 预留物理内存,也不证明 MySQL、Scert 已分别受到合适的限制;必须另行确定这些服务的预算、监控并验证持续运行。
## 部署与远程验收
1. 恢复受信任 SSH 登录,核对主机身份、线上版本、服务 PID、重启计数、完整预算及 OOM 记录。不要复用已泄露的历史密码。
2. 先执行只读检查。旧服务缺少新规则时预期失败,保留结果作为整改前证据,不能通过重置计数掩盖 OOM。
3. 用最新源码构建产物;在 47 的独立目录和隔离网络创建清洁数据库验收实例,保持硬资源上限。正式 unit 的检查使用 `systemd-analyze verify`,不得仅用字符串断言代替系统解析。
4. 在受限的远程测试单元中执行 `python3 test/deployment/resource_policy_test.py`;也可使用统一部署测试入口 `node test/run.mjs deployment`。这些测试使用模拟快照和全新临时夹具,不访问业务数据库,不替代线上资源检查。
5. 完成正式安装流程、真实网页发信队列、中文附件、内部 `127.0.0.1:25`、混合认证和受控故障恢复,记录内存峰值、延迟、繁忙响应、任务数、OOM 和同机服务状态。仅用小样本成功不能声明最大容量。
6. 预算通过后安排停服窗口,备份双程序、unit、环境文件、所有数据库和密钥证书。安装程序不会自动停止正在运行的服务,部署时保留原数据与可回退产物。
7. 部署后重新执行只读预检与内部 SMTP 回归,检查限额、线上摘要和其他服务状态;未通过时停止放行,按备份方案恢复,不扩大预算以掩盖失败。
触发启动频率限制后,先保存故障证据并处理原因,再由维护人员决定恢复启动。不能在定时任务里循环 `reset-failed`,不能把自动重启当作队列和数据库的故障验收。
## 本轮未证明的事项
尚未在 47 上执行本说明新增的测试或真实预检,尚未核实默认 512 MiB 硬上限适用于该主机。TLS、凭据轮换、完整浏览器流程、超管恢复撤销、竞态、真实跨库和异机恢复继续以《生产整改验收清单》为准,不因资源配置补齐而自动通过。
## 2026-09-17 夜间实测更新
以上为早前阻塞记录,以本节和最新远程测试记录为准。恢复 SSH 后,资源回归已远程通过,生产 GOMEMLIMIT=256MiB 和原硬限额已生效;归档 tmpfs 旧产物后连续五次原 128 MiB 保留预算检查通过。
新增 Nginx 后 22:56 再次预检通过:Smail 内存35,201,024字节、上限536,870,912字节;主机 available 724,357,120字节,增长至上限后仍满足134,217,728字节保留门槛。Nginx 当时约5.3MiB,采用一个 worker。该快照不代表峰值容量或其他服务预算已证明。
主机本轮实测已存在约4GiB swap,Smail 控制组仍禁止 swap;本轮没有创建或调整交换空间,不能沿用早期“主机无交换空间”的描述。
证书续期单元上限128MiB、SwapMax=0、Go目标64MiB、总超时240秒;首次未到期检查峰值约15.3MiB。六项异常回归在64MiB隔离单元通过。临近到期真实续期的资源峰值及外部告警尚待演练,不据此批准全机生产容量。