Browse Source

docs(sync): prepare hosting deployment handoff and record first nightly run

彭峰 1 day ago
parent
commit
c651435c87

+ 75 - 0
docs/migration/hosting-bridge-deployment-request.md

@@ -0,0 +1,75 @@
+# 小树旧系统同步桥:托管方代部署工单
+
+请在现有小树旧站上部署独立、只读的数据同步桥,并按下列条件验收。旧站仍有客户使用,请保留现有网站与数据库业务数据。
+
+## 目标和已知现场情况
+
+- 目标地址:`https://a018.2018.z01.com/xiaoshu-sync/v1/health`。
+- 2026-10-11 23:02(北京时间)实测:同步桥 HTTP 404;新系统返回 configured=false、bridgeReachable=false,所有数据集无同步成功检查点。
+- 旧站首页可访问。需要在服务器端核查实际 IIS 站点、域名绑定、`/xiaoshu-sync` 子应用及 IIS 日志子状态,确认是否未部署或映射错误。
+- 旧数据库此前核验为 `zatu2024`,SQL Server 2016 / 13.0.5026.0,服务器名 SZ02;部署时请再次确认,不得误连其他网站数据库。
+- 网站 CMS 管理账号不具备现成 IIS 发布能力,不能用模板编辑或静态站点发布替代本次安装。
+
+## 交付包
+
+交付压缩包中 `bridge/xiaoshu-legacy-sync-bridge-iis.zip` 为 Windows x64 自包含发布。请先把它展开到独立安装目录,例如 `C:\deploy\xiaoshu-legacy-sync`,以下命令均从该目录执行。
+
+桥包 SHA-256:`d1e2b65f9c81a5f7e0a2c4855a8bea2380361e11f929ca4111a79efe74cab7b9`。
+
+桥包包含 runtime、安装/测试/回滚脚本、SQL 安装及核验脚本、配置模板和 README;不包含正式密钥和连接串。三个部署脚本已与当前源码逐字比对,包内没有 appsettings.Production.json。
+
+## 部署前需填写的参数
+
+| 参数 | 负责方与要求 |
+| --- | --- |
+| 实际 IIS SiteName | 旧站托管方确认绑定 a018.2018.z01.com 的站点名称,不能直接默认 Default Web Site |
+| SQL 连接串 | 旧站托管方提供具备必要读取权限的专用连接;DDL 安装另用有权限的账号,不在工单回执中回传密码 |
+| HMAC KeyId / Secret | 部署管理员生成新的 KeyId 与至少 32 位随机 Secret,通过双方约定的安全渠道交给新系统管理员 |
+| AllowedIps | 新系统管理员提供真实服务器出口 IP;DNS 的入站 IP 或开发电脑 IP 不等于实际出口 IP |
+| 独立应用池和目录 | 建议 XiaoshuLegacySync、C:\inetpub\xiaoshu-sync;不得与旧站根应用共用应用池 |
+
+缺少其中任何一项时请明确回报缺项,不得用空配置或开放任意来源的方式代替。若当前托管套餐不支持独立 IIS 子应用,请先回报限制及可提供的独立服务/受控反向代理方案,不要只上传文件后宣布完成。
+
+## 旧站托管方操作
+
+1. 备份 IIS 配置、现有同名同步桥应用(若有)及目标数据库。记录备份路径和时间。确认 IIS 具备 AspNetCoreModuleV2;桥为自包含发布,不要求安装 .NET 8 Runtime,但需要这个 IIS 模块。
+2. 将 `deployment/appsettings.Production.template.json` 复制到 `C:\secure\xiaoshu-sync.production.json`,安全填写上述参数。PathBase 保持 `/xiaoshu-sync`;不填占位值,不将配置打包回传。
+3. 在管理员 Windows PowerShell 中确认实际站点、域名绑定并预检:
+
+   ```powershell
+   Import-Module WebAdministration
+   Get-Website | Select-Object Name, State, PhysicalPath
+   Get-WebBinding | Select-Object ItemXPath, Protocol, BindingInformation
+   $targetSite = Read-Host '绑定 a018.2018.z01.com 的实际 IIS 站点名称'
+   .\deployment\Install-XiaoshuLegacySyncBridge.ps1 -PublishPath . -ConfigurationPath C:\secure\xiaoshu-sync.production.json -SiteName $targetSite -HealthUrl https://a018.2018.z01.com/xiaoshu-sync/v1/health -PreflightOnly
+   ```
+
+4. 预检通过后安装独立应用,先确认外部健康地址能返回本桥服务身份。健康接口本身不依赖 SQL 同步表:
+
+   ```powershell
+   .\deployment\Install-XiaoshuLegacySyncBridge.ps1 -PublishPath . -ConfigurationPath C:\secure\xiaoshu-sync.production.json -SiteName $targetSite -HealthUrl https://a018.2018.z01.com/xiaoshu-sync/v1/health
+   ```
+
+5. 与新系统管理员确认消费端、凭据和后续部署准备好后,在确认过的旧库执行 `database/install.sql`,再执行 `database/verify-readonly.sql`。SQL 脚本是多个 GO 分隔的批次,应使用 SSMS/sqlcmd 的正常脚本执行方式。确认两个日志表、一个失败关闭的命令过程及 12 个变更触发器,WritesFailClosed=1。不要修改业务字段、执行写桥命令、清空变更日志或业务表。
+6. 执行真实签名与数据库读取验收;只返回健康 200 不够:
+
+   ```powershell
+   .\deployment\Test-XiaoshuLegacySyncBridge.ps1 -BaseUrl https://a018.2018.z01.com/xiaoshu-sync -ConfigurationPath C:\secure\xiaoshu-sync.production.json
+   ```
+
+   应通过健康身份、签名 manifest、11 个数据集 changes 首页读取。manifest.consistent=false 表示读取期间旧库变化,需稍后重试,不应修改程序强行判定通过。不能用静态 JSON 页面替代服务。
+7. 抽查旧站登录、首页和一项只读业务查询仍正常,保留 IIS 站点与应用的实际配置证据。回填部署回执,隐藏所有密码、Secret、令牌与学生业务内容。
+
+## 验收不通过时
+
+- 404:回报目标站点、绑定、子应用映射,以及该请求的 IIS sc-status / sc-substatus / sc-win32-status;确认包所在目录已创建为 IIS 应用。
+- 500 或启动失败:检查应用池的 64 位模式、AspNetCoreModuleV2、配置及目录权限,回传脱敏事件记录。
+- 401/403:核查签名配置、双方服务器时间及实际出口 IP 白名单,不关闭认证。
+- SQL 查询失败:核查目标数据库、对象安装、连接权限和实际错误;不以健康接口成功关闭工单。
+- 安装脚本会输出原桥备份路径;已有桥需要回滚时执行包内 Rollback 脚本并显式填写 HealthUrl。首次安装没有旧桥备份,须由托管方恢复安装前 IIS 配置或仅移除新建子应用,禁止删除旧站目录。
+
+## 新系统侧后续工作(由新系统管理员负责)
+
+旧站托管方完成桥部署不等于夜间同步完成。新系统还需安全配置 XIAOSHU_LEGACY_SYNC_BASE_URL、KEY_ID、SECRET;验收全数据集“保留新系统修改、记录冲突”和主附表原子性;完成一次真实同步及业务 ID/校验和对账,保留 684 条待核对冲突;最后安装并验收每天 Asia/Shanghai 23:00 的服务器任务。不得通过手工修改 checkpoint 或将全部冲突标记解决来通过验收。
+
+当前聊天的 23 点自动任务会记录阻塞并检查后续部署结果;它不替代服务器端作业。请按职责分工回传旧桥部署和新系统接入各自的验收结果。

+ 2 - 0
docs/migration/nightly-legacy-sync.md

@@ -12,6 +12,8 @@
 
 已通过应用工具创建并回读当前聊天的每日 23:00 自动任务,ID 为 23。它检查正式任务运行结果;尚未上线时核查同步条件,满足后执行 `npm run sync-worker:nightly`,不满足就持久保存失败原因。此聊天任务依赖电脑开机和应用运行,不能替代服务器调度。
 
+2026-10-11 首次夜间调度已触发:23:02 查询生产状态,仍未配置且当晚成功数据集为 0;正式运行入口返回 blocked / bridge_http_404,报告已保存。用户已选择由托管方代部署同步桥,交接要求见 [托管方代部署工单](hosting-bridge-deployment-request.md)。该工单和发布包已经准备,可直接交给托管方;尚未发送给外部联系人,也未取得托管方执行回执。
+
 ## 执行入口与成功标准
 
 `npm run sync-worker:nightly -- --check` 仅验收前提;`npm run sync-worker:nightly` 执行一轮。运行报告默认保存在 `~/.local/state/xiaoshu/legacy-sync/`,使用北京时间业务日期和唯一运行 ID,每次记录起止、状态、原因及各数据集计数;文件权限 0600。缺配置或接口故障也必须留下失败报告。