第 20 章 / 共 51 章
卷三 · 协议开发

vhost 实战:一个进程运营一片站群

第 8 章讲了 vhost 的机制,本章讲它的工程组织——蓝本是生产环境 home 仓库:一个 XServer 进程、14 个 vhost、动态站与纯静态站混布。

本章导读

站位:配置章(卷二)与协议章(卷三)的汇流处。本章不再讲新机制,讲"怎么把机制组织成可长期运营的站群"。

20.1 引入:生产蓝本

home 仓库(XServer 的生产部署)的真实形态:一个 xs.json、一个 server(80/443 双端点)、14 个 vhost——开发者社区、RPA 中英文站、学院、博客、文档站群(XRT/XGE/XServer 文档是 devlang=static 的纯静态 host)、测试站。每个动态站有独立脚本与证书,静态站零脚本。一个进程服务全部,一次 reload 更新任意一个站。

20.2 站群目录布局

home 仓库的 host 布局(生产实样抽象)
home/
├── xs / xs.exe / xs.json          /* 宿主与总配置 */
├── host/
│   ├── default/                   /* host_default:默认站点 */
│   │   ├── script/main.c          /*   动态站:脚本 */
│   │   ├── wwwroot/  tls/  db/
│   ├── xxdevs/                    /* 社区站(独立脚本+证书)*/
│   │   ├── script/main.c  wwwroot/  tls/
│   ├── xrt/                        /* 文档站:纯静态 */
│   │   └── wwwroot/               /*   无 script 目录 */
│   └── ...                         /* 其余站点同构 */
└── tools/ dev/                    /* 运维与开发辅助 */

刚才发生了什么:布局的三个决策——每 host 一个自包含目录(wwwroot/tls/script/db 同级,整目录可迁移);host 目录名 = 站点标识(配置里的 name/host 与目录一致,排错不用对账);静态站只是"没有 script 的 host"(devlang=static,布局同构)。

20.3 配置组织

  • 一个 server 全收 80/443:所有站共享端点,靠 Host/SNI 分流——不要给每个站开一个 server(端口管理成本转给了防火墙)
  • 证书就近放:各 host 的 tls/ 目录,SNI 表按 host 自动构建(ch08/12)
  • 多域名显式列出:"a.com;www.a.com",精确匹配无通配(ch08 的坑)
  • 默认站兜底:host_default 指向一个低风险页面(如导航页/404 说明),不要让它暴露真实业务
  • Custom 按站分发:站点私有旋钮写进各自 host 的 Custom(前缀键名,ch09)

20.4 脚本复用与隔离

14 个动态站 = 14 份独立脚本运行时。复用与隔离的平衡术:

  • 复用靠拷贝 modules/:home 的做法是把通用模块(响应辅助、数据库、模板)作为模块目录拷进需要的站——每站编译一份,无跨站符号冲突
  • 隔离是免费的:一站的静态变量、数据库句柄、崩溃都圈在自己的一代里;A 站 reload 不影响 B 站(发布单元 = host 所属 server 的 generation,但配置级分流使未变更站完全不参与)
  • 跨站共享数据走显式通道:文件系统(db/)或 xsServerFind 查询拓扑——没有隐式全局

20.5 契约

  • 布局线:host 目录自包含、目录名即站点标识、静态站同构布局。
  • 端点线:单 server 双端点全收,Host/SNI 分流。
  • 变更线:按 host 提交 reload;未变更站零参与。

常见错误

默认站放了个后台
症状
扫描器用 IP 直连(无 Host 或随机 Host)命中了管理后台。
原因
未命中 vhost 的流量全部进 host_default——它应该是最不敏感的站点。
新站上线忘了配证书
症状
新域名 TLS 握手失败或拿到别的站的证书。
原因
TLS 端点上每个 host 必须有自己的证书(SNI 表按 host 构建);只配了 host 字段没配 tls_cert/key 的 host 无法在 443 上完成身份选择。

编程练习

基础三站站群

按 20.2 布局搭:默认导航站 + 一个静态文档站 + 一个动态站(含脚本与 db 目录)。

验收:三个 Host 名各归其站;未命中进默认导航页。
进阶单站热更新

改动态站的脚本并只对该 host 提交 reload,另两站持续压测。

验收:压测零错误;日志只见目标站的换代记录。
挑战站群巡检路由

在默认站实现 /status:枚举全部 server/host 输出运行状态表(ch11 的查询 API)。

验收:输出覆盖全部站点且 State 正确;非默认站不暴露该路由。

小结

要点结论
蓝本home 生产:一进程 14 vhost,动静态混布
布局host 目录自包含;目录名即标识;静态站同构
端点单 server 全收 80/443,Host/SNI 分流
复用modules/ 拷贝复用;隔离免费;共享走显式通道
兜底host_default 放最低风险内容
本章涉及的 API 参考
xrt 延伸阅读