You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/docs/07-Windows服务状态功能-上线回滚文档.md

197 lines
7.4 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Windows 服务状态管理功能 — 上线/回滚文档
**分支**: `feat/windows-service-status-auto`
**目标**: `main`
**日期**: 2026-05-04
**PR URL**: https://git.cjy.net.cn/jcl/haoliang-net/compare/main...feat/windows-service-status-auto
---
## 一、功能概述
为 CncCollector 采集服务添加原生 Windows Service 支持,实现双模式运行(控制台调试 + Windows 服务),并在管理后台仪表盘准确展示服务运行状态(未安装/运行中/启动中/启动失败/已停止),支持远程启动/停止操作。
## 二、变更清单
### 2.1 后端变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `src/CncCollector/CncCollectorService.cs` | 新增 | ServiceBase 包装OnStart/OnStop/OnPause/OnContinue/OnShutdown |
| `src/CncCollector/ProjectInstaller.cs` | 新增 | InstallUtil 安装器配置 |
| `src/CncCollector/Program.cs` | 修改 | 双模式入口(--console 调试/无参数=服务模式/--install/--uninstall |
| `src/CncCollector/CncCollector.csproj` | 修改 | 添加 System.ServiceProcess + System.Configuration.Install 引用 |
| `src/CncService/Interface/IWindowsServiceChecker.cs` | 新增 | 服务状态检测接口 + ServiceStatusEnum 枚举 |
| `src/CncService/Impl/WindowsServiceChecker.cs` | 新增 | 基于 ServiceController 的实现 |
| `src/CncService/Impl/DashboardService.cs` | 修改 | 注入 IWindowsServiceChecker增强 GetCollectorStatus 返回 serviceStatus/serviceName/serviceMessage |
| `src/CncWebApi/Controllers/DashboardController.cs` | 修改 | StartCollector 前置状态检查NotInstalled→40001, Running→40002 |
| `src/CncWebApi/Infrastructure/ServiceResolver.cs` | 修改 | DI 注入 WindowsServiceChecker |
| `src/CncCollector/scripts/install.ps1` | 新增 | 安装脚本 v2.0InstallUtil/NSSM/SC 三级降级) |
| `src/CncCollector/scripts/uninstall.ps1` | 新增 | 卸载脚本 v2.0(三级降级卸载 + 交互式清理) |
### 2.2 前端变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `frontend/src/types/index.ts` | 修改 | CollectorStatus 接口扩展 serviceStatus/serviceName/serviceMessage 字段 |
| `frontend/src/views/dashboard/DashboardPage.vue` | 修改 | 服务状态标签映射、未安装引导提示、启动按钮逻辑 |
### 2.3 测试变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `tests/CncService.Tests/WindowsServiceCheckerTests.cs` | 新增 | 服务检测单元测试2 个用例) |
| `tests/CncService.Tests/DashboardServiceTests.cs` | 新增 | DI 场景测试3 个用例NotInstalled/Running/Starting |
### 2.4 CI/CD 变更
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `.github/workflows/ci-windows.yml` | 新增 | Windows CI 流水线(构建 + 测试 + 前端构建) |
## 三、错误码定义
| 错误码 | 含义 | 触发条件 |
|--------|------|----------|
| 40001 | 服务未安装 | Windows 中不存在 CncCollector 服务 |
| 40002 | 服务已在运行 | 服务当前状态为 Running |
| 50002 | 服务启动失败 | 启动操作超时或返回错误 |
| 50003 | 服务不可用 | 服务状态异常 |
## 四、验证结果
### 4.1 编译验证
| 项目 | 结果 | 备注 |
|------|------|------|
| dotnet build全解决方案 | ✅ 0 错误 | 82 个 CS1591 警告(既有 XML 注释缺失) |
| npm run build前端 | ✅ 0 错误 | vue-tsc 类型检查 + vite 构建通过 |
### 4.2 单元测试
| 测试用例 | 结果 |
|----------|------|
| `WindowsServiceCheckerTests.GetServiceStatus_NotInstalled_ForUnknownService` | ✅ 通过 |
| `WindowsServiceCheckerTests.TryStartService_NotInstalled_ReturnsNotInstalled` | ✅ 通过 |
| `DashboardServiceTests.GetCollectorStatus_With_NotInstalled_Service_Returns_NotInstalled_State` | ✅ 通过 |
| `DashboardServiceTests.GetCollectorStatus_With_Running_Heartbeats_Returns_Running_State` | ✅ 通过 |
| `DashboardServiceTests.GetCollectorStatus_With_Starting_ServiceStatus_Returns_Starting_State` | ✅ 通过 |
**5/5 测试全部通过。**
注:其他 55 个失败的测试为既有数据库外键约束问题,与本次改动无关。
## 五、上线步骤
### 5.1 前置条件
- 服务器192.168.1.202Windows Server
- MariaDB 11.8 已运行
- IIS 应用池 `haoliang` 已配置
- 当前 CncCollector 以控制台模式运行(需停掉)
### 5.2 上线流程
```powershell
# 1. 合并分支到 main
git checkout main
git merge feat/windows-service-status-auto
git push
# 2. 构建后端
dotnet build -c Release
# 3. 构建前端
cd frontend
npm ci
npm run build
cd ..
# 4. 部署 Web API 到 IIS
# 复制 src/CncWebApi/bin/Release 到 C:\inetpub\wwwroot\haoliang
# 复制 frontend/dist 到 C:\inetpub\wwwroot\haoliang\admin
Import-Module WebAdministration
Restart-WebAppPool -Name 'haoliang'
# 5. 停掉当前控制台模式的 CncCollector如有
# 任务管理器结束 CncCollector.exe 进程
# 6. 安装为 Windows 服务
cd src/CncCollector/scripts
.\install.ps1
# 7. 验证服务状态
Get-Service CncCollector
# 应显示 Status=Running
# 8. 验证管理后台仪表盘
# 浏览器打开 http://192.168.1.202/admin/
# 查看首页采集服务状态卡片,应显示"运行中"
```
### 5.3 验证清单
- [ ] 管理后台仪表盘服务状态显示正确
- [ ] 服务未安装时显示"未安装"并提供安装引导
- [ ] 启动按钮可远程启动服务
- [ ] 停止按钮可远程停止服务
- [ ] 服务状态实时刷新30秒心跳
- [ ] 安装脚本 install.ps1 正常工作
- [ ] 卸载脚本 uninstall.ps1 正常工作
## 六、回滚方案
### 6.1 回滚触发条件
- 服务安装失败无法启动
- 管理后台仪表盘状态显示异常
- 采集数据丢失或中断超过 10 分钟
### 6.2 回滚步骤
```powershell
# 1. 卸载 Windows 服务
cd src/CncCollector/scripts
.\uninstall.ps1
# 2. 回退代码到上一个稳定版本
git checkout main
git revert HEAD # 回退本次合并
git push
# 3. 重新部署旧版 Web API
# 从备份恢复 IIS 目录
Import-Module WebAdministration
Restart-WebAppPool -Name 'haoliang'
# 4. 恢复控制台模式运行
# 用旧版 CncCollector.exe 以控制台模式启动
Start-Process -FilePath "C:\path\to\CncCollector.exe" -ArgumentList "--console"
```
### 6.3 回滚注意事项
- 卸载服务前先停止服务
- 数据库无 schema 变更,无需回滚数据库
- 前端回滚随 IIS 部署自动恢复
- 回滚后确认采集数据恢复正常
## 七、风险评估
| 风险项 | 级别 | 应对措施 |
|--------|------|----------|
| Windows 服务权限不足 | 低 | install.ps1 自动请求管理员权限 |
| 服务安装失败 | 中 | 提供三级降级安装策略InstallUtil→NSSM→SC |
| 心跳超时误判 | 低 | 超时阈值设为 90 秒3个心跳间隔 |
| 服务启动超时 | 中 | TryStartService 默认等待 30 秒,可配置 |
| 前端类型错误 | 已修复 | CollectorStatus 接口合并、serviceStatusLabel 移入 script setup |
## 八、提交记录
| 提交 | 说明 |
|------|------|
| `6e5b296` | 增加 Windows Service 原生支持,双模式运行和服务安装卸载 |
| `9e3a759` | 修复仪表盘采集服务状态判断:增加心跳超时检测 |
| `e9802a1` | 前端适配、后端测试扩展、CI/Playwright E2E |
| `d8f5925` | 扩展 DashboardServiceTests DI 场景 |
| `0212ed6` | CI 工作流和扩展测试 |
| `acdc502` | 新增 Starting 状态测试用例 |
| (待提交) | 修复前端类型错误 + CI 配置修复 |