feat(部署): 增加双击安装服务入口(install-service.cmd)并自动验证启动结果
1个文件已添加
5个文件已修改
174 ■■■■■ 已修改文件
HANDOFF.md 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-templates/README-部署说明.txt 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-templates/backend/install-service.cmd 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-templates/backend/install-service.ps1 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/打包部署说明.md 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pack-deploy.ps1 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HANDOFF.md
@@ -43,6 +43,13 @@
- **未验证项(需在目标机做一次)**:本机当前不是管理员,**没真正 install è¿‡æœåŠ¡**;开机自启、失败重启、日志滚动要在服务器上按 README 3.1 æ‰§è¡Œä¸€æ¬¡ç¡®è®¤ã€‚
- **新包(本地,不入库)**:`deploy/traffic-audit-deploy-20261003-3/`(393 æ–‡ä»¶ / 110.49 MB,zip 83.77 MB)。已验证:服务三件套在 `backend\`、包内 `trafficAudit.exe` SHA-256 ä¸Žå›ºå®šå€¼ä¸€è‡´ã€`backend\web` ä¸Ž `frontend/dist` å„ 44 æ–‡ä»¶ã€jar åŽ»å¯†è‡ªæ£€é€šè¿‡ã€æ— æ˜Žæ–‡ key。**旧的 `traffic-audit-deploy-20261003/` ä¸Ž `-2/` å·²è¢«å–代**,部署请用 `-3`(旧包待用户确认后再删)。
- **运行状态(写本条时)**:开发用后端 8090(PID 43040)、前端 8080(PID 43152)均在跑;数据库 `127.0.0.1:3305/traffic_audit`。
- **补充可操作性(用户反馈“backend ä¸‹æ–‡ä»¶å¤ªå¤šï¼Œä¸çŸ¥é“怎么操作”)**:
  - æ–°å¢žåŒå‡»å…¥å£ `deploy-templates/backend/install-service.cmd`:自动 UAC ææƒ â†’ è°ƒ `install-service.ps1`;若找不到 `trafficAudit.exe` åˆ™æç¤ºâ€œå¿…须整个 backend ä¸€èµ·æ‹·â€ã€‚
  - `install-service.ps1` è£…完会自己探测端口(TCP æŽ¢æµ‹ï¼Œå…¼å®¹ PowerShell 2.0),打印 OK + æœ¬æœº/对外网址;起不来时直接打印 `logs\*.log` æœ€åŽ 15 è¡Œï¼›è‹¥ `application.yml` å£ä»¤ä»åƒå ä½ç¬¦ï¼Œæœ€åŽå†æ‰“一次醒目提示。
  - `README-部署说明.txt` é¡¶éƒ¨æ–°å¢žã€æœåŠ¡å™¨ä¸Šåªè¦åšè¿™ 3 æ­¥ã€‘+“哪些要拷/哪些不用拷”;`docs/打包部署说明.md` çš„ 5.4 æ”¹ä¸ºâ€œå³é”® `install-service.cmd` â†’以管理员运行”。
  - ä¸‰ä¸ª `.cmd` æ¨¡æ¿ç»Ÿä¸€ä¸º CRLF(新增的两个原来是 LF,批处理在 Windows ä¸Šåº”用 CRLF)。
  - å®žæµ‹ï¼šå¼ºåˆ¶èµ°â€œå·²ææƒâ€åˆ†æ”¯æ—¶ `cmd â†’ install-service.ps1 -Status` é“¾è·¯è·‘通、`%*` ä¼ å‚正常;`Test-LocalPort` å¯¹ 8090 è¿”回 True、对 8099 è¿”回 False。
  - æ–°åŒ…:`deploy/traffic-audit-deploy-20261003-4/`(394 æ–‡ä»¶ / 110.50 MB,zip 83.78 MB)——**当前最新可用包**;`20261003` / `-2` / `-3` å‡å·²è¢«å–代,待用户确认后清理。
## æœ€æ–°ï¼ˆ2026-10-02)
deploy-templates/README-²¿Êð˵Ã÷.txt
@@ -1,6 +1,21 @@
TrafficAudit äº¤é€šè´§è¿ç»Ÿè®¡å®¡æ ¸ç³»ç»Ÿ â€”— éƒ¨ç½²åŒ…({stamp})
========================================================
【服务器上只要做这 3 æ­¥ã€‘(其它文件都不用动)
  ç¬¬ 1 æ­¥  æ”¹é…ç½®ï¼šç”¨è®°äº‹æœ¬æ‰“å¼€ backend\application.yml,把数据库地址/账号/密码
           ï¼ˆspring.datasource ä¸‹é¢ä¸‰é¡¹ï¼‰å’Œ jwt.secret æ”¹æˆè¿™å°æœåŠ¡å™¨çš„çœŸå®žå€¼ã€‚
  ç¬¬ 2 æ­¥  è£…服务:进入 backend æ–‡ä»¶å¤¹ï¼Œå³é”® install-service.cmd â†’「以管理员身份运行」
           ï¼ˆç›´æŽ¥åŒå‡»ä¹Ÿè¡Œï¼Œå®ƒä¼šè‡ªå·±å¼¹ç®¡ç†å‘˜ç¡®è®¤ï¼‰ã€‚脚本会注册开机自启服务并启动它。
  ç¬¬ 3 æ­¥  çœ‹ç»“果:脚本最后会打印 OK å’Œç½‘址;浏览器打开 http://<服务器IP>:8090
           ï¼ˆè´¦å· admin / admin123),能看到登录页就算成功。
  å“ªäº›è¦æ‹·ã€å“ªäº›ä¸ç”¨æ‹·ï¼š
    backend\   å¿…须整个目录一起拷(jar、application.yml、docs、web、服务文件都在里面),
               ä¸è¦åªæŒ‘几个文件拷。
    db\        åªæœ‰éœ€è¦åˆå§‹åŒ–/还原数据库时才用,平时可不拷。
    frontend\  ä¸ç”¨æ‹·ï¼ˆå‰ç«¯å·²å†…嵌在 jar é‡Œï¼Œ8090 ç«¯å£ç›´æŽ¥è®¿é—®ï¼‰ã€‚
    æœ¬æ–‡ä»¶      å¯æ‹·å¯ä¸æ‹·ï¼Œå°±æ˜¯è¿™ä»½è¯´æ˜Žä¹¦ã€‚
【目录结构】
  backend/
    traffic-audit-server-1.0.0-SNAPSHOT.jar  åŽç«¯ç¨‹åºï¼ˆå«å…¨éƒ¨ä¾èµ–,**已内嵌前端**)
@@ -9,7 +24,8 @@
    start-backend.cmd / start-backend.sh     å‰å°å¯åŠ¨è„šæœ¬ï¼ˆäººå·¥è°ƒè¯•ç”¨ï¼Œå…³äº†çª—å£å°±åœï¼‰
    trafficAudit.exe                         WinSW æœåŠ¡åŒ…è£…å™¨ï¼ˆæŠŠ java å˜æˆ Windows æœåŠ¡ï¼Œå‹¿åˆ å‹¿æ”¹åï¼‰
    trafficAudit.xml                         WinSW æœåŠ¡é…ç½®ï¼ˆæœåŠ¡å/启动方式/日志/失败重启策略)
    install-service.ps1                      æ³¨å†Œ/查看/重启/删除 Windows æœåŠ¡ï¼ˆå¼€æœºè‡ªå¯ï¼ŒæŽ¨èï¼‰
    install-service.cmd                      åŒå‡»å…¥å£ï¼šæ³¨å†Œå¼€æœºè‡ªå¯æœåŠ¡ï¼ˆä¼šè‡ªåŠ¨è¯·æ±‚ç®¡ç†å‘˜æƒé™ï¼‰
    install-service.ps1                      ä¸Šé¢é‚£ä¸ª cmd å®žé™…调用的脚本(注册/查看/重启/删除)
    start-backend-service.cmd                éžäº¤äº’启动器(无 pause、写 app.log,配合计划任务用)
    install-autostart.ps1                    å¤‡é€‰ï¼šæ³¨å†Œâ€œè®¡åˆ’任务”方式的开机自启
  frontend/
@@ -61,15 +77,17 @@
     - deepseek.api-key ï¼šéœ€è¦ AI åˆ†æžæ—¶å¡«ï¼Œä¸éœ€è¦å¯ç•™ç©º
     æ³¨ï¼šapplication.yml ä¸Ž jar åŒçº§å³ç”Ÿæ•ˆï¼Œä¸ç”¨é‡æ–°æ‰“包。
  3. å¯åŠ¨åŽç«¯ï¼ˆåœ¨ backend ç›®å½•下)
  3. å¯åŠ¨åŽç«¯ï¼ˆåœ¨ backend ç›®å½•下;这步只是手工试跑,关窗口就停,要开机自启请看 3.1)
     Windows:双击 start-backend.cmd
     Linux:  sh start-backend.sh
     æˆåŠŸæ ‡å¿—ï¼šå‡ºçŽ° "Started TrafficAuditApplication" ä¸Ž "Tomcat started on port(s): 8090"
  3.1 Windows å¼€æœºè‡ªå¯ï¼ˆæŽ¨èï¼šæ³¨å†Œæˆ Windows æœåŠ¡ï¼Œä¸€æ¬¡é…ç½®é•¿æœŸç”Ÿæ•ˆï¼‰
     å‰æï¼šbackend ç›®å½•下的 trafficAudit.exe / trafficAudit.xml / install-service.ps1 éƒ½å·²éšæœ¬éƒ¨ç½²åŒ…提供,
           ä¸éœ€è¦å¦å¤–下载 WinSW,也不需要给 java è£…别的东西。
     åœ¨ backend ç›®å½•下,用【管理员】PowerShell æ‰§è¡Œï¼š
     å‰æï¼šbackend ç›®å½•下的 trafficAudit.exe / trafficAudit.xml / install-service.cmd / install-service.ps1
           éƒ½å·²éšæœ¬éƒ¨ç½²åŒ…提供,不需要另外下载 WinSW,也不需要给 java è£…别的东西。
     æœ€çœäº‹ï¼šåœ¨ backend ç›®å½•右键 install-service.cmd â†’「以管理员身份运行」
             ï¼ˆç›´æŽ¥åŒå‡»ä¹Ÿè¡Œï¼Œå®ƒä¼šè‡ªå·±å¼¹ UAC ç®¡ç†å‘˜ç¡®è®¤ï¼‰ã€‚
     ç­‰ä»·çš„æ‰‹å·¥æ–¹å¼ï¼ˆåœ¨ backend ç›®å½•下,用【管理员】PowerShell):
       powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1
     æ•ˆæžœï¼šæ³¨å†Œ Windows æœåŠ¡ TrafficAuditBackend,开机自动启动(延迟启动,先等 MySQL å°±ç»ªï¼‰ï¼Œ
           ä¸éœ€è¦ä»»ä½•用户登录;java è¿›ç¨‹å¼‚常退出由服务管理器自动重启(10 ç§’ / 30 ç§’ / 60 ç§’递增重试,
@@ -82,8 +100,9 @@
       -NoStart                          åªæ³¨å†Œä¸å¯åЍ    -JavaPath "D:\jdk8\bin\java.exe"  æ‰‹åŠ¨æŒ‡å®š JDK
     æ—¥å¿—:backend\logs\trafficAudit.out.log(运行输出)与 trafficAudit.err.log(错误输出),
           å•个文件 10MB,保留 10 ä¸ªæ»šåŠ¨æ–‡ä»¶ã€‚
     éªŒè¯ï¼šæµè§ˆå™¨æ‰“å¼€ http://<部署机IP>:8090 ï¼Œæˆ–
           (Invoke-WebRequest http://127.0.0.1:8090 -UseBasicParsing).StatusCode
     éªŒè¯ï¼šè„šæœ¬è£…å®Œä¼šè‡ªåŠ¨æŽ¢æµ‹ç«¯å£ï¼Œæ‰“å° OK + æœ¬æœº/对外网址;起不来时直接打印 logs\*.log æœ€åŽ 15 è¡Œï¼Œ
           æŒ‰æç¤ºæ”¹ application.yml åŽæ‰§è¡Œ install-service.ps1 -Restart å³å¯ã€‚也可手工用浏览器打开
           http://<部署机IP>:8090 ç¡®è®¤ã€‚
     æ³¨æ„ï¼š
       - å¼€æœºè‡ªå¯é æœåŠ¡çš„â€œè‡ªåŠ¨â€å¯åŠ¨ç±»åž‹ï¼›å¦‚æžœæŠŠå®ƒæ”¹æˆâ€œæ‰‹åŠ¨â€ï¼Œå°±ä¸ä¼šå†éšæœºå™¨å¯åŠ¨ã€‚
       - é‡å¤æ‰§è¡Œ install-service.ps1 æ˜¯å®‰å…¨çš„:会先停服务再重新注册并启动。
deploy-templates/backend/install-service.cmd
New file
@@ -0,0 +1,49 @@
@echo off
rem ============================================================
rem  Double-click entry point for a fresh Windows server:
rem  installs the TrafficAudit backend as a Windows service
rem  (auto-start at boot) and then verifies it comes up.
rem
rem  It asks for Administrator rights (UAC) and then runs
rem  install-service.ps1 from this folder.
rem
rem  If double-clicking does nothing, right-click this file and
rem  choose "Run as administrator".
rem
rem  ASCII-only on purpose: cmd.exe reads this file with the OEM
rem  code page.
rem ============================================================
setlocal
cd /d "%~dp0"
if not exist "%~dp0trafficAudit.exe" (
  echo [ERROR] trafficAudit.exe was not found next to this script.
  echo         Copy the WHOLE backend folder to the server, do not
  echo         pick single files out of it.
  echo.
  pause
  exit /b 1
)
rem S-1-16-12288 = High Mandatory Level, i.e. this window is already elevated.
whoami /groups | findstr /C:"S-1-16-12288" >nul 2>&1
if errorlevel 1 (
  echo Administrator rights are required. A UAC prompt will appear now.
  powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
  if errorlevel 1 (
    echo.
    echo [ERROR] Automatic elevation failed.
    echo         Right-click install-service.cmd and choose
    echo         "Run as administrator" instead.
    echo.
    pause
  )
  exit /b
)
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0install-service.ps1" %*
echo.
echo ------------------------------------------------------------
echo  Finished. Press any key to close this window.
pause >nul
deploy-templates/backend/install-service.ps1
@@ -129,6 +129,23 @@
  Get-Service -Name $serviceId -ErrorAction SilentlyContinue
}
function Test-LocalPort {
  param([int]$Port, [string]$TargetHost = '127.0.0.1')
  # Probe TCP instead of HTTP: Invoke-WebRequest does not exist on Windows
  # PowerShell 2 (Windows 7), and this works on every PowerShell version.
  $client = New-Object System.Net.Sockets.TcpClient
  try {
    $async = $client.BeginConnect($TargetHost, $Port, $null, $null)
    if ($async.AsyncWaitHandle.WaitOne(1000, $false) -and $client.Connected) { return $true }
    return $false
  } catch {
    return $false
  } finally {
    $client.Close()
  }
}
# ---------- read-only status: no elevation needed ----------
if ($Status) {
  $service = Get-ServiceState
@@ -180,6 +197,7 @@
if (-not (Test-Path $wrapper)) {
  throw "Missing wrapper executable: $wrapper`nRebuild the deploy package with pack-deploy.ps1 (it provides WinSW), or copy WinSW-x64.exe here renamed to trafficAudit.exe."
}
$passwordOk = $false
if (-not (Test-Path $appConfig)) {
  Write-Host "WARN: application.yml is missing next to the jar."
  Write-Host "      The built-in password placeholder resolves to an empty string and startup will fail with"
@@ -195,6 +213,8 @@
    } elseif ($value -match '[^\x00-\x7F]') {
      Write-Host "WARN: the datasource password contains non-ASCII characters."
      Write-Host "      If it is still the Chinese placeholder text, replace it with the real MySQL password first."
    } else {
      $passwordOk = $true
    }
  }
}
@@ -218,18 +238,59 @@
if ($LASTEXITCODE -ne 0) { throw "WinSW install failed with exit code $LASTEXITCODE" }
if (-not $NoStart) {
  Write-Host "Starting service '$serviceId' (delayed auto-start is used at boot)..."
  Write-Host "Starting service '$serviceId' (auto-start at boot is enabled)..."
  & $wrapper start
  Start-Sleep -Seconds 8
  Start-Sleep -Seconds 5
  $service = Get-ServiceState
  $service | Select-Object Name, DisplayName, Status, StartType | Format-List
  $serviceDir = Join-Path $root 'logs'
  # Read the port from application.yml so the check matches the real config.
  $port = 8090
  if (Test-Path $appConfig) {
    $portLine = Select-String -LiteralPath $appConfig -Pattern '^\s*port\s*:' | Select-Object -First 1
    if ($portLine -and $portLine.Line -match '(\d{2,5})') { $port = [int]$matches[1] }
  }
  $ready = $false
  for ($i = 1; $i -le 30; $i++) {
    if (Test-LocalPort -Port $port) { $ready = $true; break }
    Start-Sleep -Seconds 2
    $state = Get-ServiceState
    if ($state -and $state.Status -ne 'Running') { break }
  }
  $logDir = Join-Path $root 'logs'
  Write-Host ''
  Write-Host "Logs        : $serviceDir\trafficAudit.out.log / trafficAudit.err.log"
  Write-Host "Health check: (Invoke-WebRequest http://127.0.0.1:8090 -UseBasicParsing).StatusCode"
  if ($ready) {
    Write-Host "OK  : the backend is listening on port $port."
    Write-Host "      On this server   : http://127.0.0.1:$port"
    Write-Host "      For other people : http://<server-ip>:$port"
  } else {
    Write-Host "WARN: nothing is listening on port $port yet - startup is still running, or it failed."
    Write-Host "      Fix application.yml / MySQL, then run: .\install-service.ps1 -Restart"
    foreach ($name in @('trafficAudit.err.log', 'trafficAudit.out.log')) {
      $logFile = Join-Path $logDir $name
      if (Test-Path -LiteralPath $logFile) {
  Write-Host ''
  Write-Host "Manage it with: Stop-Service $serviceId | Start-Service $serviceId"
  Write-Host "Or: .\install-service.ps1 -Status | -Restart | -Remove"
        Write-Host "---- last 15 lines of $name ----"
        Get-Content -LiteralPath $logFile -Tail 15 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host "  $_" }
      }
    }
  }
  if (-not $passwordOk) {
  Write-Host ''
  Write-Host 'The service auto-starts on every boot (Automatic, delayed start).'
    Write-Host '=============================================================='
    Write-Host ' IMPORTANT: backend\application.yml still looks unset.'
    Write-Host ' Put the real MySQL url / username / password in it, then run'
    Write-Host '   .\install-service.ps1 -Restart'
    Write-Host '=============================================================='
  }
  Write-Host ''
  Write-Host "Logs  : $logDir\trafficAudit.out.log / trafficAudit.err.log"
  Write-Host "Manage: .\install-service.ps1 -Status | -Restart | -Remove"
  Write-Host "        Stop-Service $serviceId | Start-Service $serviceId"
  Write-Host ''
  Write-Host 'This service starts automatically on every boot (Automatic + delayed start).'
}
docs/´ò°ü²¿Êð˵Ã÷.md
@@ -58,7 +58,8 @@
│  â”œâ”€ start-backend.cmd / start-backend.sh      å¯åŠ¨è„šæœ¬ï¼ˆäººå·¥åŒå‡»/命令行)
│  â”œâ”€ trafficAudit.exe                          WinSW æœåŠ¡åŒ…è£…å™¨ï¼ˆ2.12.0 x64,自包含 .NET 6)
│  â”œâ”€ trafficAudit.xml                          WinSW æœåŠ¡é…ç½®ï¼ˆè‡ªåŠ¨/延迟启动、失败重启、日志滚动)
│  â”œâ”€ install-service.ps1                       æ³¨å†Œ/查看/重启/删除 Windows æœåŠ¡ï¼ˆå¼€æœºè‡ªå¯ï¼ŒæŽ¨èï¼‰
│  â”œâ”€ install-service.cmd                       åŒå‡»å…¥å£ï¼šæ³¨å†Œå¼€æœºè‡ªå¯æœåŠ¡ï¼ˆè‡ªåŠ¨è¯·æ±‚ç®¡ç†å‘˜æƒé™ï¼‰
│  â”œâ”€ install-service.ps1                       ä¸Šé¢é‚£ä¸ª cmd å®žé™…调用的脚本(注册/查看/重启/删除)
│  â”œâ”€ start-backend-service.cmd                 å¤‡é€‰ï¼šéžäº¤äº’启动器(无 pause、写 app.log)
│  â”œâ”€ install-autostart.ps1                     å¤‡é€‰ï¼šæ³¨å†Œ/查看/删除 Windows å¼€æœºè‡ªå¯è®¡åˆ’任务
│  â””─ web/                                     å‰ç«¯é™æ€æ–‡ä»¶ï¼ˆç”± dist è‡ªåŠ¨åŒæ­¥ï¼Œ8090 å•端口模式必需)
@@ -171,12 +172,14 @@
### 5.4 Windows å¼€æœºè‡ªå¯ï¼ˆæŽ¨èï¼šæ³¨å†Œæˆ Windows æœåŠ¡ï¼‰
在 `backend` ç›®å½•下用**管理员** PowerShell æ‰§è¡Œï¼ˆ`trafficAudit.exe` / `trafficAudit.xml` / `install-service.ps1` å·²éšåŒ…提供):
在 `backend` ç›®å½•里**右键 `install-service.cmd` â†’「以管理员身份运行」**即可(直接双击也行,它会自己弹 UAC)。它实际调用的就是同目录的 `install-service.ps1`,等价命令:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1
```
脚本会自动定位 java、注册服务、启动,然后探测端口打印结果;起不来时直接打印 `logs\*.log` çš„æœ€åŽ 15 è¡Œã€‚
| é¡¹ | å€¼ |
|----|----|
| æœåŠ¡å | `TrafficAuditBackend`(services.msc é‡Œæ˜¾ç¤ºä¸º TrafficAudit Backend) |
pack-deploy.ps1
@@ -173,6 +173,7 @@
  Copy-Item -LiteralPath $winswSrc (Join-Path $dest 'backend\trafficAudit.exe') -Force
  Copy-Item (Join-Path $tplDir 'backend\trafficAudit.xml') (Join-Path $dest 'backend') -Force
  Copy-Item (Join-Path $tplDir 'backend\install-service.ps1') (Join-Path $dest 'backend') -Force
  Copy-Item (Join-Path $tplDir 'backend\install-service.cmd') (Join-Path $dest 'backend') -Force
}
Copy-Item $webDist (Join-Path $dest 'frontend') -Recurse -Force
Copy-Item (Join-Path $tplDir 'frontend\nginx.conf.example') (Join-Path $dest 'frontend') -Force