|
|
@@ -0,0 +1,278 @@
|
|
|
+# Windows 后端 WinSW 守护重启方案
|
|
|
+
|
|
|
+## 目标
|
|
|
+
|
|
|
+将后端 `Admin.NET.Web.Entry` 以 Windows Service 方式运行,由 WinSW 负责:
|
|
|
+
|
|
|
+- 开机自启
|
|
|
+- 异常退出后自动重启
|
|
|
+- 标准输出 / 错误输出落盘
|
|
|
+- 统一服务启停与状态查看
|
|
|
+
|
|
|
+适用场景:Windows 服务器上部署已发布的 ASP.NET Core 后端,例如:
|
|
|
+
|
|
|
+```text
|
|
|
+D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry
|
|
|
+```
|
|
|
+
|
|
|
+## 推荐架构
|
|
|
+
|
|
|
+```mermaid
|
|
|
+flowchart LR
|
|
|
+ client["Browser"] --> proxy["Nginx or IIS"]
|
|
|
+ proxy --> frontend["Web dist static files"]
|
|
|
+ proxy -->|"proxy /prod-api"| backendService["AiDOPBackend Windows Service"]
|
|
|
+ backendService --> backendProcess["dotnet Admin.NET.Web.Entry.dll"]
|
|
|
+ backendProcess --> mysql["MySQL"]
|
|
|
+```
|
|
|
+
|
|
|
+推荐职责划分:
|
|
|
+
|
|
|
+- WinSW:只负责后端进程守护。
|
|
|
+- Nginx / IIS:负责 80 / 443 入口、HTTPS、静态前端、反向代理。
|
|
|
+- 后端:监听本机或内网端口,例如 `5005`。
|
|
|
+- MySQL:由数据库自身高可用、备份与监控保障。
|
|
|
+
|
|
|
+## 部署目录建议
|
|
|
+
|
|
|
+建议发布后端到固定目录:
|
|
|
+
|
|
|
+```text
|
|
|
+D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry
|
|
|
+```
|
|
|
+
|
|
|
+目录示例:
|
|
|
+
|
|
|
+```text
|
|
|
+web-entry\
|
|
|
+ Admin.NET.Web.Entry.dll
|
|
|
+ Admin.NET.Web.Entry.exe
|
|
|
+ appsettings.json
|
|
|
+ Configuration\
|
|
|
+ wwwroot\
|
|
|
+ AiDOPBackendService.exe
|
|
|
+ AiDOPBackendService.xml
|
|
|
+ logs\
|
|
|
+```
|
|
|
+
|
|
|
+说明:
|
|
|
+
|
|
|
+- `AiDOPBackendService.exe` 是 WinSW 可执行文件重命名后的文件。
|
|
|
+- `AiDOPBackendService.xml` 是 WinSW 服务配置,文件名需与 exe 主文件名一致。
|
|
|
+- `logs\` 用于保存 WinSW 重定向日志。
|
|
|
+
|
|
|
+## 获取 WinSW
|
|
|
+
|
|
|
+从 WinSW 官方发布页下载适合 Windows 的可执行文件:
|
|
|
+
|
|
|
+- 项目地址:https://github.com/winsw/winsw
|
|
|
+- 常用文件:`WinSW-x64.exe`
|
|
|
+
|
|
|
+下载后重命名为:
|
|
|
+
|
|
|
+```text
|
|
|
+AiDOPBackendService.exe
|
|
|
+```
|
|
|
+
|
|
|
+并放入后端发布目录。
|
|
|
+
|
|
|
+## WinSW 配置示例
|
|
|
+
|
|
|
+在同目录创建 `AiDOPBackendService.xml`:
|
|
|
+
|
|
|
+```xml
|
|
|
+<service>
|
|
|
+ <id>AiDOPBackend</id>
|
|
|
+ <name>AiDOP Backend</name>
|
|
|
+ <description>AiDOP Admin.NET backend service</description>
|
|
|
+
|
|
|
+ <executable>dotnet</executable>
|
|
|
+ <arguments>Admin.NET.Web.Entry.dll</arguments>
|
|
|
+ <workingdirectory>D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry</workingdirectory>
|
|
|
+
|
|
|
+ <env name="ASPNETCORE_ENVIRONMENT" value="Production" />
|
|
|
+ <env name="ASPNETCORE_URLS" value="http://0.0.0.0:5005" />
|
|
|
+
|
|
|
+ <logpath>D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry\logs</logpath>
|
|
|
+ <log mode="roll-by-size-time">
|
|
|
+ <sizeThreshold>10485760</sizeThreshold>
|
|
|
+ <pattern>yyyyMMdd</pattern>
|
|
|
+ </log>
|
|
|
+
|
|
|
+ <onfailure action="restart" delay="10 sec" />
|
|
|
+ <onfailure action="restart" delay="30 sec" />
|
|
|
+ <onfailure action="restart" delay="60 sec" />
|
|
|
+</service>
|
|
|
+```
|
|
|
+
|
|
|
+关键点:
|
|
|
+
|
|
|
+- `workingdirectory` 必须指向发布目录,否则配置、静态资源、相对路径可能找不到。
|
|
|
+- `ASPNETCORE_URLS` 与反向代理目标保持一致。
|
|
|
+- `ASPNETCORE_ENVIRONMENT` 建议生产使用 `Production`;若当前仍依赖开发配置,需要先确认配置加载路径。
|
|
|
+- `onfailure` 不要设置过于密集,避免启动失败时高速重启刷爆日志和数据库。
|
|
|
+
|
|
|
+## 服务安装与管理
|
|
|
+
|
|
|
+以管理员权限打开 PowerShell,进入发布目录:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Set-Location "D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry"
|
|
|
+```
|
|
|
+
|
|
|
+安装服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe install
|
|
|
+```
|
|
|
+
|
|
|
+启动服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe start
|
|
|
+```
|
|
|
+
|
|
|
+查看状态:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe status
|
|
|
+```
|
|
|
+
|
|
|
+停止服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe stop
|
|
|
+```
|
|
|
+
|
|
|
+卸载服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe uninstall
|
|
|
+```
|
|
|
+
|
|
|
+也可以通过系统服务管理器查看服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+services.msc
|
|
|
+```
|
|
|
+
|
|
|
+## 发布更新流程
|
|
|
+
|
|
|
+建议发布时按以下顺序执行:
|
|
|
+
|
|
|
+1. 构建后端:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Set-Location "D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server"
|
|
|
+dotnet publish "Admin.NET.Web.Entry\Admin.NET.Web.Entry.csproj" -c Release -f net10.0 -o ".publish\web-entry"
|
|
|
+```
|
|
|
+
|
|
|
+2. 停止服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Set-Location "D:\Projects\Ai-DOP\SourceCode\ZZYDOP\server\.publish\web-entry"
|
|
|
+.\AiDOPBackendService.exe stop
|
|
|
+```
|
|
|
+
|
|
|
+3. 覆盖发布产物。
|
|
|
+
|
|
|
+4. 启动服务:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe start
|
|
|
+```
|
|
|
+
|
|
|
+5. 验证监听端口:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Get-NetTCPConnection -LocalPort 5005 -State Listen
|
|
|
+```
|
|
|
+
|
|
|
+6. 验证 HTTP:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Invoke-WebRequest -Uri "http://127.0.0.1:5005" -UseBasicParsing
|
|
|
+```
|
|
|
+
|
|
|
+## 与前端 / 反向代理的配合
|
|
|
+
|
|
|
+前端建议使用生产构建产物:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Set-Location "D:\Projects\Ai-DOP\SourceCode\ZZYDOP\Web"
|
|
|
+pnpm run build
|
|
|
+```
|
|
|
+
|
|
|
+然后由 Nginx 或 IIS 托管 `Web/dist`。
|
|
|
+
|
|
|
+反向代理建议:
|
|
|
+
|
|
|
+- 前端静态资源由 Nginx / IIS 直接返回。
|
|
|
+- `/prod-api` 反向代理到 `http://127.0.0.1:5005`。
|
|
|
+- 外部只暴露 80 / 443,不直接暴露 5005。
|
|
|
+
|
|
|
+## 健康检查建议
|
|
|
+
|
|
|
+建议后端提供健康检查接口,例如:
|
|
|
+
|
|
|
+```text
|
|
|
+GET /health
|
|
|
+```
|
|
|
+
|
|
|
+检查内容建议分层:
|
|
|
+
|
|
|
+- 基础存活:进程是否能响应。
|
|
|
+- 数据库:MySQL 是否可连接。
|
|
|
+- 核心依赖:必要的缓存、文件存储、第三方服务是否可用。
|
|
|
+
|
|
|
+外部探活脚本或监控系统可定期请求:
|
|
|
+
|
|
|
+```powershell
|
|
|
+Invoke-WebRequest -Uri "http://127.0.0.1:5005/health" -UseBasicParsing -TimeoutSec 5
|
|
|
+```
|
|
|
+
|
|
|
+如果短期没有 `/health`,可临时使用 `/` 或稳定 API 做探活,但不建议长期依赖页面入口。
|
|
|
+
|
|
|
+## 日志与排障
|
|
|
+
|
|
|
+建议至少保留三类日志:
|
|
|
+
|
|
|
+- WinSW stdout / stderr:服务进程启动、崩溃、最外层异常输出。
|
|
|
+- 应用日志:Admin.NET / Furion / 业务日志。
|
|
|
+- 反向代理日志:访问日志、错误日志、502 / 504 等。
|
|
|
+
|
|
|
+常用排障命令:
|
|
|
+
|
|
|
+```powershell
|
|
|
+.\AiDOPBackendService.exe status
|
|
|
+Get-Service AiDOPBackend
|
|
|
+Get-NetTCPConnection -LocalPort 5005 -State Listen
|
|
|
+Get-Process -Name dotnet
|
|
|
+```
|
|
|
+
|
|
|
+如果服务反复重启:
|
|
|
+
|
|
|
+1. 先看 WinSW 日志。
|
|
|
+2. 再看应用日志。
|
|
|
+3. 确认 `appsettings` / `Configuration` / 数据库连接串是否来自预期环境。
|
|
|
+4. 确认 MySQL 是否可达。
|
|
|
+5. 确认端口 5005 是否被其他进程占用。
|
|
|
+
|
|
|
+## 注意事项
|
|
|
+
|
|
|
+- WinSW 只能在进程退出后拉起,不能修复应用内部逻辑错误。
|
|
|
+- `StackOverflowException`、本机访问冲突、`Environment.FailFast` 等仍可能直接终止进程;WinSW 的作用是让服务尽快恢复并留下日志。
|
|
|
+- 不建议生产环境直接运行 `pnpm dev` 或 `vite preview` 作为正式前端服务。
|
|
|
+- 不建议生产环境在每次启动时自动执行大范围 CodeFirst DDL;数据库结构变更应尽量走显式迁移脚本。
|
|
|
+- 如果后端有定时任务,多实例部署前必须确认是否会重复执行;单机 WinSW 守护不涉及该问题。
|
|
|
+
|
|
|
+## 推荐落地顺序
|
|
|
+
|
|
|
+1. 固定后端发布目录。
|
|
|
+2. 下载并放置 WinSW。
|
|
|
+3. 编写 `AiDOPBackendService.xml`。
|
|
|
+4. 安装并启动 Windows Service。
|
|
|
+5. 验证 5005 监听与 HTTP 响应。
|
|
|
+6. 配置 Nginx / IIS 反代。
|
|
|
+7. 配置日志轮转与监控告警。
|
|
|
+8. 演练异常退出后的自动重启。
|