| .gitignore | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| HANDOFF.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| deploy-templates/README-部署说明.txt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| deploy-templates/backend/install-autostart.ps1 | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| deploy-templates/backend/install-service.ps1 | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| deploy-templates/backend/start-backend-service.cmd | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| deploy-templates/backend/trafficAudit.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| docs/打包部署说明.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pack-deploy.ps1 | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
.gitignore
@@ -72,6 +72,9 @@ web/ traffic-audit-server/web/ # ==== Windows æå¡å è£ å¨ï¼WinSW äºè¿å¶ï¼17.4MBï¼ç± pack-deploy.ps1 ä¸è½½å¹¶æ ¡éª SHA-256ï¼ä¸å ¥åºï¼==== deploy-templates/tools/ # ==== é¨ç½²äº§ç©ï¼ä¸å ¥åºï¼==== deploy/ traffic-audit-deploy-*.zip HANDOFF.md
@@ -28,6 +28,22 @@ - **Git/å·¥ä½åºï¼æ¬æ®µæ´æ°åï¼**ï¼`HEAD = origin/main = 37f5209`ï¼å½åæ å·²è·è¸ªæä»¶æ¹å¨ãæªè·è¸ªé¡¹æ `_tmp_holiday_verify/`ï¼åå²éªè¯äº§ç©ï¼å `docs.zip`ï¼çº¦ 31.6 MBï¼ç¨æ·æ¬å°äº§ç©ï¼ï¼äºè åä¿çï¼æ°å¯¹è¯ä¸è¦è¯¯å æè¯¯æäº¤ã - **ä¸ä¸æ¥**ï¼å¦éé¨ç½²ï¼ç´æ¥ä½¿ç¨ä¸é¢åå¸ç®å½æ zipï¼å¦éç»§ç»ä¿®å¤åå¸å·¥å ·ï¼å å®ç°âå ä½ç¬¦æ¨¡æ¿èªå¨åæ¢ + `backend/web` èªå¨ç»è£ + jar å»å¯èªæ£âååéæ°äº§åºåå¸å ã ### Windows 弿ºèªå¯ï¼10-03 追å ï¼ç¨æ·éâæ¹æ¡ Bâï¼æ³¨åæ Windows æå¡ï¼ - **å åçè¿çé®é¢**ï¼`start-backend.cmd` **ä¸è½**ç´æ¥å弿ºèªå¯ï¼æ«å°¾æ `pause`ãæ æ¥å¿éå®åãä¾èµ PATHï¼ãç»åº Aï¼è®¡åä»»å¡ï¼/Bï¼Windows æå¡ï¼/C 䏿¹æ¡åï¼ç¨æ·é **B**ã - **æ°å¢æ¨¡æ¿ï¼å·²å ¥åºï¼**ï¼ - `deploy-templates/backend/trafficAudit.xml`ï¼WinSW æå¡é ç½®ââid `TrafficAuditBackend`ã`startmode=Automatic` + `delayedAutoStart=true`ï¼ç MySQL å 就绪ï¼ã`onfailure restart 10s/30s/60s` + `resetfailure 1 hour`ã`workingdirectory=%BASE%`ãæ¥å¿ `logs\trafficAudit.out.log|err.log`ï¼10MB à 10 æ»å¨ï¼ã - `deploy-templates/backend/install-service.ps1`ï¼ç®¡çåå®è£ /æ¥ç/éå¯/å é¤ï¼`-Status/-Restart/-Remove/-NoStart/-JavaPath`ï¼ï¼èªå¨å®ä½ javaï¼JAVA_HOME â PATH â JavaSoft 注å表 â Program Filesï¼å¹¶æç»å¯¹è·¯å¾åè¿ XML ç `executable` å ç´ ï¼é夿§è¡å¹çï¼é管çåç´æ¥æç»ã - `start-backend-service.cmd` + `install-autostart.ps1`ï¼è®¡å任塿¹å¼ï¼ä¿ç为**å¤é**ï¼æ³¨æ `New-ScheduledTask*` é Win8/Server 2012+ï¼ä¸**ä¸å¯ä¸æå¡æ¹å¼åæ¶å¯ç¨**ï¼ä¼æ¢ 8090ï¼ã - `pack-deploy.ps1`ï¼æ°å¢ WinSW è·åï¼ç¼å `deploy-templates/tools/winsw.exe` å¹¶æ ¡ SHA-256ï¼ç¼ºåä» GitHub ä¸è½½ v2.12.0 x64ï¼ä¸ `-SkipServiceWrapper`ï¼å å è¾åº `backend\trafficAudit.exe`ï¼æ¹å以å¹é XML æä»¶åï¼ã`.gitignore` æ°å¢ `deploy-templates/tools/`ï¼17.4MB äºè¿å¶ä¸å ¥åºï¼ã - **WinSW = Windows Service Wrapper**ï¼ææ®éç¨åºå æ Windows æå¡ãjava.exe èªå·±ä¸æ¯æå¡ç¨åºï¼ç´æ¥ `sc create` 伿¥âæå¡æ²¡æåæ¶ååºå¯å¨ææ§å¶è¯·æ±âï¼WinSW å®ç°äºæå¡æ§å¶åè®®åæèµ· `java -jar`ï¼å¹¶ç®¡éå¯ä¸æ¥å¿ã - **宿µéªè¯ï¼æ¬æºï¼æªçæ£å®è£ æå¡ï¼**ï¼`trafficAudit.exe status` è½è¯»æå XML å¹¶è¾åº `NonExistent`ï¼è§£æéè¿ï¼ï¼æ æåå XML â `FATAL - The configuration file cound not be loaded`ï¼è¯æè¯¥æ ¡éªè·¯å¾ç宿æï¼ï¼`install-service.ps1 -Status` æ£å¸¸è¾åºâæªå®è£ âï¼æ åæ° / `-Remove` å¨é管çå䏿âå¿ é¡»ç®¡çåâä¸ä¸äº§ç注å项ã - **踩åï¼éè¦ï¼**ï¼XML æ¹åæåç¨æ£å `(?s)<executable>.*?</executable>`ï¼ä¼**å å½ä¸æ³¨ééç `<executable>` åæ ·**ï¼ææ³¨éå¤´ä¸ service å¼å¤´æ´æ®µåæ â XML éæ³ãå·²æ¹ä¸º DOMï¼`SelectSingleNode('/service/executable')`ï¼å¹¶ææ³¨ééç裸æ ç¾æ¹æãå¦ï¼æ°å¢æå ä»£ç æ¾å¤ä¸ä¸ª `}` 导è´è¯æ³éï¼å·²ç¨ `Parser::ParseFile` AST 夿 ¸ï¼ä¸¤ä¸ª ps1 ç°å¨è¯æ³ OK ä¸å为 UTF-8 with BOMã - **å ¼å®¹æ§ï¼ç¨æ·é®âWin7/Win10/Win11/Server æ¯ä¸æ¯é½å¯ä»¥âï¼**ï¼æå¡æºå¶å®å ¨ä¸æ ·ï¼èªå¨å¯å¨/å»¶è¿å¯å¨/失败éå¯é½æ¯ç³»ç»è½åï¼ï¼å·®å«åªå¨å è£ å¨ä¾èµä»ä¹è¿è¡æ¶ã宿µäºè¿å¶ï¼`WinSW-x64.exe` 2.12.0 æ¯**èªå å« .NET 6 åæä»¶**ï¼å« `singlefilehost`/`System.Private.CoreLib`/`Microsoft.NETCore.App 6.0.13`/`net6.0`ï¼ï¼**ä¸éè¦è£ .NET Framework**ï¼èç³»ç»ï¼Win7 SP1/2008R2/2012R2ï¼è¥æ¥ `api-ms-win-*.dll` 缺失ï¼å¯æ¢å®æ¹ `WinSW.NET461.exe`ï¼0.6MBï¼é .NET 4.6.1+ï¼æ¹åæ `trafficAudit.exe` å³å¯ï¼XML ä¸å¨ï¼ï¼32 ä½ç³»ç»æ¢ `WinSW-x86.exe`ã - **å®å ¨æç¤º**ï¼WinSW 宿¹äº§ç©**æªå Authenticode ç¾å**ï¼æ¬æº `Get-AuthenticodeSignature` = NotSignedï¼ï¼å æ¤ä»¥åºå® SHA-256 ä½å®æ´æ§æ ¡éªï¼`05B82D46AD331CC16BDC00DE5C6332C1EF818DF8CEEFCD49C726553209B3A0DA`ï¼ä¸ GitHub åå¸èµäº§ 18,243,033 åèä¸è´ï¼ã - **æªéªè¯é¡¹ï¼éå¨ç®æ æºå䏿¬¡ï¼**ï¼æ¬æºå½å䏿¯ç®¡çåï¼**æ²¡çæ£ 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`ã ## ææ°ï¼2026-10-02ï¼ - **æ°æ¨¡åï¼ç¨æ·å·²éªæ¶ï¼æ¬æ¬¡æäº¤/æ¨éï¼**ï¼æ°å¢âä¸é¡¹ç»è®¡-éè¦èåæ¥âæ¨¡åï¼å«è忥é ç½®ãè¥ä¸æ§å®¢æµãéè¥ä¸æ§è½¦æµã客è¿ç³»æ° 4 å¼ è¡¨ï¼ç³»ç»é ç½®èåä» admin å¯ç»´æ¤ï¼ä¸é¡¹ç»è®¡-èåæ¥æ¯æå¯¼å ¥ã导åºã模æ¿ä¸è½½å Word å¿«æ¥ä¸è½½ã deploy-templates/README-²¿Êð˵Ã÷.txt
@@ -6,7 +6,12 @@ traffic-audit-server-1.0.0-SNAPSHOT.jar å端ç¨åºï¼å«å ¨é¨ä¾èµï¼**å·²å åµå端**ï¼ docs/ æ¥è¡¨æ¨¡æ¿ä¸è¿è¡æ°æ®ç®å½ï¼å¿ éï¼å¿å ï¼ application.yml å¤é¨é ç½®ï¼æ¹è¿éå³å¯ï¼æ ééæ°æå ï¼ start-backend.cmd / start-backend.sh å¯å¨èæ¬ start-backend.cmd / start-backend.sh åå°å¯å¨èæ¬ï¼äººå·¥è°è¯ç¨ï¼å ³äºçªå£å°±åï¼ trafficAudit.exe WinSW æå¡å è£ å¨ï¼æ java åæ Windows æå¡ï¼å¿å å¿æ¹åï¼ trafficAudit.xml WinSW æå¡é ç½®ï¼æå¡å/å¯å¨æ¹å¼/æ¥å¿/失败éå¯çç¥ï¼ install-service.ps1 注å/æ¥ç/éå¯/å é¤ Windows æå¡ï¼å¼æºèªå¯ï¼æ¨èï¼ start-backend-service.cmd é交äºå¯å¨å¨ï¼æ pauseãå app.logï¼é å计åä»»å¡ç¨ï¼ install-autostart.ps1 å¤éï¼æ³¨åâ计åä»»å¡âæ¹å¼ç弿ºèªå¯ frontend/ dist/ å端æå»ºäº§ç©ï¼å¤ç¨ï¼æ³ç¨ nginx æç®¡æ¶ç¨ï¼ nginx.conf.example nginx é ç½®ç¤ºä¾ @@ -25,6 +30,21 @@ MySQL 5.7 / 8.0ï¼å¿ éï¼ **ä¸éè¦ Redis**ï¼ä»£ç æªä½¿ç¨ï¼æ§ç说æéç Redis æ¯éçé ç½®ï¼å¯å¿½ç¥ï¼ **ä¸éè¦ nginx**ï¼å端已å åµè¿ jarï¼è®¿é® 8090 å³å¯ï¼nginx ä» ä¸ºå¤éæ¹æ¡ï¼ ãæä½ç³»ç»å ¼å®¹æ§ã 弿ºèªå¯ç¨çæ¯ Windows æå¡ï¼èâèªå¨å¯å¨ / å»¶è¿å¯å¨ / 失败èªå¨éå¯âæ¯ç³»ç»èªå¸¦è½åï¼ ä» Win7 SP1 å° Win11ãServer 2008 R2 å° Server 2022/2025 æºå¶å®å ¨ä¸æ ·ãå·®å«åªå¨æå¡å è£ å¨ trafficAudit.exe ä¾èµä»ä¹è¿è¡æ¶ï¼ - æ¬å å ç trafficAudit.exe æ¯ WinSW 2.12.0 ç x64 èªå å«æå»ºï¼èªå¸¦ .NET 6 è¿è¡æ¶ï¼å·²æ ¡éª SHA-256ï¼ï¼ **ä¸éè¦å¦å¤å®è£ .NET Framework**ï¼æ¨èç¨äº 64 ä½ Win10 / Win11 / Server 2016 å以ä¸ã - Win7 SP1 / Server 2008 R2 / Server 2012(R2)ï¼èªå å«çé常ä¹è½è·ï¼Win7 SP1 éå æ KB2533623ï¼ï¼ è¥æ¥ç¼ºå° api-ms-win-*.dll ä¹ç±»ï¼æ¢æå®æ¹ thin æå»ºï¼æ WinSW.NET461.exe ä¸è½½åæ¹åæ trafficAudit.exe è¦çï¼é ç½® trafficAudit.xml ä¸ç¨æ¹ï¼ï¼å®é .NET Framework 4.6.1+ï¼ https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW.NET461.exe - 32 ä½ç³»ç»ï¼æå è£ å¨æ¢æ WinSW-x86.exeï¼åä¸ä¸è½½é¡µï¼ã - Win7 / Server 2012 æ¬èº«å·²è¿å¾®è½¯æ¯ææï¼æ°æå¡å¨å»ºè®®ç´æ¥ä¸ Server 2016 å以ä¸ã - èæ¬è¦æ±ï¼install-service.ps1 å¨ Windows PowerShell 2.0+ ä¸å¯ç¨ï¼Win7 èªå¸¦ 2.0ï¼å·²åå ¼å®¹ï¼ï¼ 3.2 ç计åä»»å¡èæ¬ç¨å°äº New-ScheduledTask* å½ä»¤ï¼éè¦ Win8 / Server 2012 å以ä¸ã ãé¨ç½²æ¥éª¤ã 1. åå§åæ°æ®åºï¼4 ä¸ªèæ¬é½è¦æ§è¡ï¼é¡ºåºå¦ä¸ï¼ @@ -45,6 +65,40 @@ 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 æ§è¡ï¼ powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 ææï¼æ³¨å Windows æå¡ TrafficAuditBackendï¼å¼æºèªå¨å¯å¨ï¼å»¶è¿å¯å¨ï¼å ç MySQL 就绪ï¼ï¼ ä¸éè¦ä»»ä½ç¨æ·ç»å½ï¼java è¿ç¨å¼å¸¸éåºç±æå¡ç®¡çå¨èªå¨éå¯ï¼10 ç§ / 30 ç§ / 60 ç§éå¢éè¯ï¼ 1 å°æ¶åéè¯è®¡æ°æ¸ é¶ï¼ãæå¡ä»¥ LocalSystem 身份è¿è¡ã èæ¬ä¼èªå¨å®ä½ java.exeï¼JAVA_HOME â PATH â JavaSoft 注å表 â Program Filesï¼ï¼ å¹¶æç»å¯¹è·¯å¾åè¿ trafficAudit.xmlï¼SYSTEM æå¡ç PATH ä¸ç»å½ç¨æ·ä¸åï¼åç»å¯¹è·¯å¾æ´ç¨³ï¼ã 常ç¨åæ°ï¼ -Status æ¥çæå¡ç¶æï¼ä¸éè¦ç®¡çåï¼ -Restart éå¯æå¡ -Remove 忢并å é¤æå¡ -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 注æï¼ - 弿ºèªå¯é æå¡çâèªå¨âå¯å¨ç±»åï¼å¦ææå®æ¹æâæå¨âï¼å°±ä¸ä¼åéæºå¨å¯å¨ã - é夿§è¡ install-service.ps1 æ¯å®å ¨çï¼ä¼å åæå¡åéæ°æ³¨åå¹¶å¯å¨ã - åä¸å°æºä¸è¦åæ¶å¯ç¨ä¸é¢ç计å任塿¹å¼ï¼ä¸¤ä¸ªè¿ç¨ä¼æ¢ 8090 端å£ã - 建议æé¨ç½²å æ¾å¨ D:\trafficAudit è¿ç±»ç®åè·¯å¾ï¼æ¾å¨æäºç¨æ·ç®å½ä¸æ¶ LocalSystem å¯è½æ²¡æåæéï¼æ¥å¿ä¼æ¥æéé误ã 3.2 å¤éï¼è®¡å任塿¹å¼ï¼ä¸æ³æåç«¯è£ ææå¡æ¶ç¨ï¼ä¸ 3.1 äºéä¸ï¼ å¨ backend ç®å½ä¸ï¼ç¨ã管çåãPowerShell æ§è¡ï¼ powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 ææï¼æ³¨å计åä»»å¡ TrafficAuditBackendï¼å¼æºå»¶è¿ 60 ç§å以 SYSTEM 身份è¿è¡ start-backend-service.cmdï¼ ä¸éè¦ç¨æ·ç»å½ï¼å¤±è´¥èªå¨éè¯ 3 次ï¼è¿è¡æ¥å¿åå¨ backend\app.logã 常ç¨åæ°ï¼-DelaySeconds 90ï¼æ¹å»¶è¿ç§æ°ï¼ -StartNowï¼æ³¨ååç«å³å¯å¨ä¸æ¬¡ï¼ -Statusï¼æ¥çç¶æï¼ -Removeï¼å é¤å¼æºèªå¯ï¼ 注ï¼å¯å¨å¨ä¼å ç¨ JAVA_HOME\bin\java.exeï¼æ¾ä¸å°æ¶åé PATHï¼æ£æµå° 8090 å·²å¨çå¬åç´æ¥éåºã 4. 访é®ç³»ç» æµè§å¨æå¼ http://<é¨ç½²æºIP>:8090 ï¼å端已å åµï¼é¡µé¢ä¸æ¥å£åæºï¼ @@ -69,7 +123,15 @@ 3. 8090 端å£è¢«å ç¨ï¼æ¹ application.yml ç server.port åéå¯ã 4. 页颿弿¯ç©ºç½ï¼ç¡®è®¤è®¿é®çæ¯ http://<IP>:8090 æ ¹è·¯å¾ï¼ä¸æµè§å¨å¼ºå¶å·æ°ï¼Ctrl+F5ï¼ã 5. ä¸ä¼ 大æä»¶å¤±è´¥ï¼å端éå¶ 100MBï¼å·²é ç½®ï¼å¦åé¢è¿æäº nginxï¼é忥æ¾å¤§ client_max_body_sizeã 6. æå¡å·²æ³¨åä½ 8090 æä¸å¼ï¼ç backend\logs\trafficAudit.err.log çæ¥éå å®¹ï¼ æå¡æ¹å¼ä¸ç¨çæ¯ backend\application.ymlï¼password å¿ é¡»æ¯çå® MySQL å¯ç ï¼å 使åä¼å¯¼è´ using password: NOï¼ã 7. æå¡æ¥âæç»è®¿é®âæåä¸äºæ¥å¿ï¼é¨ç½²ç®å½æéä¸è¶³ã æé¨ç½²å æ¾å° D:\trafficAudit è¿ç±»ç®åè·¯å¾ï¼æç» LocalSystem æäºè¯¥ç®å½ç读åæéã 8. æ³ä¸´æ¶åæ¶å¼æºèªå¯ä½ä¿çæå¡ï¼Set-Service TrafficAuditBackend -StartupType Manual ã忢æå¡ã Windowsï¼å ³é start-backend.cmd çªå£ æå¡æ¹å¼ï¼ Stop-Service TrafficAuditBackend ï¼éæ°å¯å¨ï¼Start-Service TrafficAuditBackendï¼ å½»åºå é¤å¼æºèªå¯ï¼install-service.ps1 -Remove åå°å¯å¨ï¼ å ³é start-backend.cmd çªå£ 计åä»»å¡ï¼ Stop-ScheduledTask -TaskName TrafficAuditBackend Linuxï¼ Ctrl+Cï¼æ kill å¯¹åº java è¿ç¨ï¼ps -ef | grep javaï¼ deploy-templates/backend/install-autostart.ps1
New file @@ -0,0 +1,109 @@ <# Register / remove / inspect a Windows Scheduled Task that starts the TrafficAudit backend at machine boot, with no user session required. Run from an ELEVATED PowerShell in the backend folder (jar + application.yml + this script + start-backend-service.cmd): powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 -DelaySeconds 90 powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 -StartNow powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 -Status powershell -NoProfile -ExecutionPolicy Bypass -File install-autostart.ps1 -Remove What it does: - trigger : AtStartup, delayed by -DelaySeconds (default 60s, so MySQL is up first) - principal: SYSTEM, highest privileges, "run whether user is logged on or not" - settings : no execution time limit, start when available, restart 3x / 1 min on failure - action : cmd.exe /c start-backend-service.cmd (logs to app.log next to the jar) Notes: - Re-running without -Remove is idempotent (-Force overwrites the task). - Start/stop manually with: Start-ScheduledTask / Stop-ScheduledTask -TaskName <name> - Keep this file ASCII-only: Windows PowerShell 5.1 reads a BOM-less .ps1 as ANSI. #> param( [string]$TaskName = 'TrafficAuditBackend', [int]$DelaySeconds = 60, [switch]$Remove, [switch]$Status, [switch]$StartNow ) $ErrorActionPreference = 'Stop' $root = Split-Path -Parent $MyInvocation.MyCommand.Path $launcher = Join-Path $root 'start-backend-service.cmd' $logFile = Join-Path $root 'app.log' function Assert-Admin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($identity) if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'This script must run from an elevated (Run as Administrator) PowerShell.' } } if ($Status) { $task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if (-not $task) { Write-Host "Scheduled task '$TaskName' is not registered."; exit 1 } $task | Select-Object TaskName, TaskPath, State | Format-List Get-ScheduledTaskInfo -TaskName $TaskName | Select-Object LastRunTime, LastTaskResult, NextRunTime, NumberOfMissedRuns | Format-List exit 0 } if ($Remove) { Assert-Admin if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) { Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false Write-Host "Removed scheduled task '$TaskName'." } else { Write-Host "Scheduled task '$TaskName' was not registered; nothing to remove." } exit 0 } Assert-Admin if (-not (Test-Path $launcher)) { throw "Missing launcher: $launcher" } if (-not (Test-Path (Join-Path $root 'traffic-audit-server-1.0.0-SNAPSHOT.jar'))) { Write-Host "WARN: jar not found in $root - the task will be registered, but startup will fail until the jar is there." } $action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument ('/c "' + $launcher + '"') -WorkingDirectory $root $trigger = New-ScheduledTaskTrigger -AtStartup if ($DelaySeconds -gt 0) { $trigger.Delay = 'PT' + $DelaySeconds + 'S' } $principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest $settings = New-ScheduledTaskSettingsSet ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -StartWhenAvailable ` -MultipleInstances IgnoreNew ` -RestartCount 3 ` -RestartInterval (New-TimeSpan -Minutes 1) ` -ExecutionTimeLimit ([TimeSpan]::Zero) Register-ScheduledTask ` -TaskName $TaskName ` -Action $action ` -Trigger $trigger ` -Principal $principal ` -Settings $settings ` -Description 'TrafficAudit backend auto-start at machine boot (script-managed).' ` -Force | Out-Null Write-Host "Registered scheduled task '$TaskName'." Write-Host " Trigger : At startup, +${DelaySeconds}s" Write-Host " Principal: SYSTEM (highest privileges, no logon required)" Write-Host " Launcher : $launcher" Write-Host " Log : $logFile" Write-Host '' Write-Host "Service address after boot: http://<server-ip>:8090" Write-Host "Manage it with: -Status | -StartNow | -Remove" if ($StartNow) { Start-ScheduledTask -TaskName $TaskName Write-Host "Started task '$TaskName' now." } deploy-templates/backend/install-service.ps1
New file @@ -0,0 +1,235 @@ <# Install / update / remove the TrafficAudit backend as a Windows service. The service is a WinSW (Windows Service Wrapper) host: trafficAudit.exe reads trafficAudit.xml and runs "java -jar traffic-audit-server-<version>.jar". Because it is a real Windows service it starts at boot with no user logged on, is listed in services.msc / Get-Service, and is restarted by the Service Control Manager when the java process dies. Run from an ELEVATED PowerShell in the backend folder (the folder that contains the jar, application.yml, docs, web and trafficAudit.exe): powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 -Status powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 -Restart powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 -Remove powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 -NoStart powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 -JavaPath 'D:\jdk8\bin\java.exe' What it does: 1. locates java.exe (JAVA_HOME -> PATH -> JavaSoft registry -> Program Files) 2. writes that absolute path into trafficAudit.xml (<executable>) 3. installs or reinstalls the service and starts it (unless -NoStart) Notes: - Re-running is idempotent: an existing service is stopped and reinstalled. - Logs: logs\trafficAudit.out.log / logs\trafficAudit.err.log (10 MB x 10 roll). - Do NOT enable the scheduled-task autostart (install-autostart.ps1) at the same time: two hosts would race for the same jar and port 8090. - Keep this file ASCII-only; Windows PowerShell 5.1 reads a BOM-less .ps1 as ANSI. #> param( [switch]$Remove, [switch]$Status, [switch]$Restart, [switch]$NoStart, [string]$JavaPath ) $ErrorActionPreference = 'Stop' $root = Split-Path -Parent $MyInvocation.MyCommand.Path $wrapper = Join-Path $root 'trafficAudit.exe' $config = Join-Path $root 'trafficAudit.xml' $appConfig = Join-Path $root 'application.yml' $serviceId = 'TrafficAuditBackend' function Assert-Admin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($identity) if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'This script must run from an elevated (Run as Administrator) PowerShell.' } } function Resolve-JavaPath { param([string]$Explicit) if ($Explicit) { if (-not (Test-Path $Explicit)) { throw "JavaPath does not exist: $Explicit" } return (Resolve-Path $Explicit).Path } if ($env:JAVA_HOME) { $candidate = Join-Path $env:JAVA_HOME 'bin\java.exe' if (Test-Path $candidate) { return (Resolve-Path $candidate).Path } } $onPath = Get-Command java.exe -ErrorAction SilentlyContinue if ($onPath -and $onPath.Source) { return $onPath.Source } # A SYSTEM service inherits the machine PATH, which often lacks the JDK. # Fall back to the install locations used by Oracle / OpenJDK installers. foreach ($reg in @('HKLM:\SOFTWARE\JavaSoft\JDK', 'HKLM:\SOFTWARE\JavaSoft\Java Development Kit')) { if (-not (Test-Path $reg)) { continue } foreach ($ver in (Get-ChildItem $reg -ErrorAction SilentlyContinue | Sort-Object Name -Descending)) { $home = (Get-ItemProperty -Path $ver.PSPath -Name JavaHome -ErrorAction SilentlyContinue).JavaHome if ($home) { $candidate = Join-Path $home 'bin\java.exe' if (Test-Path $candidate) { return (Resolve-Path $candidate).Path } } } } $roots = @($env:ProgramFiles) if (${env:ProgramFiles(x86)}) { $roots += ${env:ProgramFiles(x86)} } foreach ($base in $roots) { foreach ($vendor in @('Java', 'Eclipse Adoptium', 'AdoptOpenJDK', 'Microsoft')) { $hit = Get-ChildItem -Path (Join-Path $base ($vendor + '\*\bin\java.exe')) -ErrorAction SilentlyContinue | Sort-Object FullName -Descending | Select-Object -First 1 if ($hit) { return $hit.FullName } } } throw 'java.exe not found. Install a JDK 8 and re-run, or pass -JavaPath "D:\path\to\bin\java.exe".' } function Set-WrapperJavaPath { param([string]$JavaExe) if (-not (Test-Path $config)) { throw "Missing config file: $config" } # Edit through the DOM: a regex would also hit the executable mention inside # the header comment and would mangle the whole document. $doc = New-Object System.Xml.XmlDocument $doc.PreserveWhitespace = $true $doc.Load($config) $node = $doc.SelectSingleNode('/service/executable') if (-not $node) { throw "No /service/executable element found in $config" } if ($node.InnerText -eq $JavaExe) { Write-Host "Config already points at $JavaExe" return } $node.InnerText = $JavaExe $settings = New-Object System.Xml.XmlWriterSettings $settings.Encoding = New-Object System.Text.UTF8Encoding $false $settings.Indent = $true $settings.IndentChars = ' ' $writer = [System.Xml.XmlWriter]::Create($config, $settings) try { $doc.Save($writer) } finally { $writer.Close() } Write-Host "Updated $config -> $JavaExe" } function Get-ServiceState { Get-Service -Name $serviceId -ErrorAction SilentlyContinue } # ---------- read-only status: no elevation needed ---------- if ($Status) { $service = Get-ServiceState if (-not $service) { Write-Host "Service '$serviceId' is NOT installed." exit 1 } $service | Select-Object Name, DisplayName, Status, StartType | Format-List # Get-CimInstance needs PowerShell 3+; fall back to WMI for Windows 7 / PowerShell 2. $detail = $null try { $detail = Get-CimInstance Win32_Service -Filter "Name='$serviceId'" -ErrorAction Stop } catch { $detail = Get-WmiObject Win32_Service -Filter "Name='$serviceId'" -ErrorAction SilentlyContinue } if ($detail) { $detail | Select-Object ProcessId, StartMode, DelayedAutoStart, PathName | Format-List } if (Test-Path $wrapper) { & $wrapper status } exit 0 } if ($Restart) { Assert-Admin if (-not (Get-ServiceState)) { throw "Service '$serviceId' is not installed; run this script without -Restart first." } Write-Host "Restarting service '$serviceId'..." Restart-Service -Name $serviceId -Force Start-Sleep -Seconds 3 Get-ServiceState | Select-Object Name, Status | Format-List exit 0 } if ($Remove) { Assert-Admin if (-not (Test-Path $wrapper)) { throw "Missing wrapper executable: $wrapper" } if (Get-ServiceState) { Write-Host "Stopping and removing service '$serviceId'..." & $wrapper stop | Out-Null Start-Sleep -Seconds 3 & $wrapper uninstall | Out-Null Write-Host "Removed service '$serviceId'. Files in $root were left untouched." } else { Write-Host "Service '$serviceId' is not installed; nothing to remove." } exit 0 } # ---------- install / reinstall ---------- Assert-Admin 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." } 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" Write-Host " Java SQLException: Access denied for user 'root'@'localhost' (using password: NO)." } else { $line = Select-String -LiteralPath $appConfig -Pattern '^\s*password\s*:' | Select-Object -First 1 if (-not $line) { Write-Host "WARN: no 'password:' entry found in application.yml; check the datasource block." } else { $value = ($line.Line -replace '^\s*password\s*:\s*', '').Trim(' ''', '"') if ($value -eq '') { Write-Host "WARN: spring.datasource.password is empty in application.yml; startup may fail with '(using password: NO)'." } 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." } } } $java = Resolve-JavaPath -Explicit $JavaPath Set-WrapperJavaPath -JavaExe $java $existing = Get-ServiceState if ($existing) { Write-Host "Service '$serviceId' already exists (status: $($existing.Status)); reinstalling..." if ($existing.Status -ne 'Stopped') { & $wrapper stop | Out-Null Start-Sleep -Seconds 3 } & $wrapper uninstall | Out-Null Start-Sleep -Seconds 2 } Write-Host "Installing service '$serviceId'..." & $wrapper install 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)..." & $wrapper start Start-Sleep -Seconds 8 $service = Get-ServiceState $service | Select-Object Name, DisplayName, Status, StartType | Format-List $serviceDir = 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" Write-Host '' Write-Host "Manage it with: Stop-Service $serviceId | Start-Service $serviceId" Write-Host "Or: .\install-service.ps1 -Status | -Restart | -Remove" Write-Host '' Write-Host 'The service auto-starts on every boot (Automatic, delayed start).' } deploy-templates/backend/start-backend-service.cmd
New file @@ -0,0 +1,49 @@ @echo off rem ============================================================ rem Non-interactive launcher for Task Scheduler / boot auto-start. rem Differences from start-backend.cmd (which is meant for a human): rem - no "pause" at the end (nobody can press a key during boot) rem - all output goes to app.log next to this file rem - resolves java via JAVA_HOME first, then PATH rem - exits 0 immediately if port 8090 is already listening rem ASCII-only on purpose: cmd.exe reads this file with the OEM rem code page, so non-ASCII text here would be garbled. rem Registered by install-autostart.ps1; run under the account that rem owns the deployment folder (SYSTEM by default). rem ============================================================ setlocal cd /d "%~dp0" set "APP_JAR=traffic-audit-server-1.0.0-SNAPSHOT.jar" set "LOG=%~dp0app.log" netstat -ano | findstr /C:":8090" | findstr /I "LISTENING" >nul 2>nul if not errorlevel 1 ( echo [%date% %time%] port 8090 is already listening; nothing to do. >> "%LOG%" exit /b 0 ) if not exist "%~dp0%APP_JAR%" ( echo [%date% %time%] ERROR: %APP_JAR% not found in "%CD%". >> "%LOG%" exit /b 1 ) set "JAVA_EXE=" if defined JAVA_HOME if exist "%JAVA_HOME%\bin\java.exe" set "JAVA_EXE=%JAVA_HOME%\bin\java.exe" if not defined JAVA_EXE for %%J in (java.exe) do set "JAVA_EXE=%%~$PATH:J" if not defined JAVA_EXE ( echo [%date% %time%] ERROR: java.exe not found. Install JDK 8 or set JAVA_HOME / PATH. >> "%LOG%" exit /b 1 ) if not exist "%~dp0application.yml" ( echo [%date% %time%] WARN: application.yml is missing next to the jar. >> "%LOG%" echo [%date% %time%] The DB password placeholder will resolve to empty and startup will fail with >> "%LOG%" echo [%date% %time%] "Access denied ... (using password: NO)". >> "%LOG%" ) echo [%date% %time%] starting backend: "%JAVA_EXE%" -jar "%APP_JAR%" (cwd "%CD%") >> "%LOG%" "%JAVA_EXE%" -jar "%~dp0%APP_JAR%" >> "%LOG%" 2>&1 set "RC=%ERRORLEVEL%" echo [%date% %time%] backend exited with code %RC%. >> "%LOG%" endlocal & exit /b %RC% deploy-templates/backend/trafficAudit.xml
New file @@ -0,0 +1,45 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- WinSW (Windows Service Wrapper) configuration for the TrafficAudit backend. Layout requirement: this file MUST stay in the same folder as the wrapper executable named trafficAudit.exe, the application jar, application.yml, docs\ and web\. WinSW looks for a config file whose name matches the executable (trafficAudit.exe -> trafficAudit.xml). %BASE% is expanded by WinSW to the folder that holds this file, so the service always runs with that folder as its working directory. The executable element below is rewritten with an absolute java.exe path by install-service.ps1 (a SYSTEM service does not inherit the interactive user PATH, so relying on PATH alone is fragile). --> <service> <id>TrafficAuditBackend</id> <name>TrafficAudit Backend</name> <description>TrafficAudit freight statistics audit backend (Spring Boot, HTTP port 8090).</description> <executable>java.exe</executable> <arguments>-Dfile.encoding=UTF-8 -jar "%BASE%\traffic-audit-server-1.0.0-SNAPSHOT.jar"</arguments> <workingdirectory>%BASE%</workingdirectory> <!-- Start at boot, but delayed so a local MySQL service is ready first. --> <startmode>Automatic</startmode> <delayedAutoStart>true</delayedAutoStart> <!-- Restart on crash: quickly at first, then back off. Counter resets after 1 hour. --> <onfailure action="restart" delay="10 sec"/> <onfailure action="restart" delay="30 sec"/> <onfailure action="restart" delay="60 sec"/> <resetfailure>1 hour</resetfailure> <stoptimeout>30 sec</stoptimeout> <logpath>%BASE%\logs</logpath> <log mode="roll-by-size"> <sizeThreshold>10240</sizeThreshold> <keepFiles>10</keepFiles> </log> <outfile>trafficAudit.out.log</outfile> <errfile>trafficAudit.err.log</errfile> </service> docs/´ò°ü²¿Êð˵Ã÷.md
@@ -55,7 +55,13 @@ â ââ traffic-audit-server-1.0.0-SNAPSHOT.jar å端 + å åµå端ï¼çº¦ 55 MBï¼ â ââ docs/ 模æ¿ä¸è¿è¡æ°æ®ï¼å¿ éï¼å¿å ï¼ â ââ application.yml å¤é¨é ç½®ï¼æ¹è¿éå³å¯ï¼æ ééæå ï¼ â ââ start-backend.cmd / start-backend.sh å¯å¨èæ¬ â ââ start-backend.cmd / start-backend.sh å¯å¨èæ¬ï¼äººå·¥åå»/å½ä»¤è¡ï¼ â ââ trafficAudit.exe WinSW æå¡å è£ å¨ï¼2.12.0 x64ï¼èªå å« .NET 6ï¼ â ââ trafficAudit.xml WinSW æå¡é ç½®ï¼èªå¨/å»¶è¿å¯å¨ã失败éå¯ãæ¥å¿æ»å¨ï¼ â ââ install-service.ps1 注å/æ¥ç/éå¯/å é¤ Windows æå¡ï¼å¼æºèªå¯ï¼æ¨èï¼ â ââ start-backend-service.cmd å¤éï¼é交äºå¯å¨å¨ï¼æ pauseãå app.logï¼ â ââ install-autostart.ps1 å¤éï¼æ³¨å/æ¥ç/å é¤ Windows 弿ºèªå¯è®¡åä»»å¡ â ââ web/ åç«¯éææä»¶ï¼ç± dist èªå¨åæ¥ï¼8090 åç«¯å£æ¨¡å¼å¿ éï¼ ââ frontend/ â ââ dist/ å端产ç©ï¼ä» nginx æ¹æ¡éè¦ï¼ â ââ nginx.conf.example nginx é ç½®ç¤ºä¾ @@ -163,7 +169,41 @@ æåæ å¿ï¼æ¥å¿åºç° `Started TrafficAuditApplication` ä¸ `Tomcat started on port(s): 8090`ã ### 5.4 è®¿é® ### 5.4 Windows 弿ºèªå¯ï¼æ¨èï¼æ³¨åæ Windows æå¡ï¼ å¨ `backend` ç®å½ä¸ç¨**管çå** PowerShell æ§è¡ï¼`trafficAudit.exe` / `trafficAudit.xml` / `install-service.ps1` å·²éå æä¾ï¼ï¼ ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File install-service.ps1 ``` | 项 | å¼ | |----|----| | æå¡å | `TrafficAuditBackend`ï¼services.msc éæ¾ç¤ºä¸º TrafficAudit Backendï¼ | | å¯å¨ç±»å | èªå¨ + å»¶è¿å¯å¨ï¼å ç MySQL 就绪ï¼ï¼ä¸éè¦ä»»ä½ç¨æ·ç»å½ | | è¿è¡èº«ä»½ | LocalSystem | | 失败éå¯ | 10s / 30s / 60s éå¢ï¼1 å°æ¶åè®¡æ°æ¸ é¶ï¼ç±æå¡æ§å¶ç®¡ç卿§è¡ï¼ | | æ¥å¿ | `backend\logs\trafficAudit.out.log`ã`trafficAudit.err.log`ï¼10MB à 10 æ»å¨ï¼ | 常ç¨åæ°ï¼`-Status`ï¼æ é管çåï¼ã`-Restart`ã`-Remove`ã`-NoStart`ã`-JavaPath "D:\jdk8\bin\java.exe"`ã èæ¬ä¼èªå¨å®ä½ `java.exe`ï¼JAVA_HOME â PATH â JavaSoft 注å表 â Program Filesï¼å¹¶æ**ç»å¯¹è·¯å¾**åè¿ `trafficAudit.xml`ï¼SYSTEM æå¡ç PATH ä¸ç»å½ç¨æ·ä¸åï¼åç»å¯¹è·¯å¾æ´ç¨³ï¼ãé夿§è¡æ¯å¹ççï¼å åæå¡åéæ°æ³¨åå¹¶å¯å¨ã > åä¸å°æº**ä¸è¦**åæ¶å¯ç¨è®¡å任塿¹å¼ï¼`install-autostart.ps1`ï¼ï¼ä¸¤ä¸ªå®¿ä¸»ä¼æ¢ 8090 端å£ã #### æä½ç³»ç»å ¼å®¹æ§ æå¡æ¬èº«ï¼èªå¨å¯å¨ / å»¶è¿å¯å¨ / 失败éå¯ï¼ä» Win7 SP1 å° Win11ãServer 2008 R2 å° Server 2022/2025 æºå¶ä¸è´ï¼å·®å«åªå¨å è£ å¨ä¾èµçè¿è¡æ¶ï¼ | ç®æ ç³»ç» | ç¨åªä¸ªå è£ å¨ | é¢å¤ä¾èµ | |----------|--------------|----------| | Win10 / Win11 / Server 2016 å以ä¸ï¼æ¨èï¼ | å å `trafficAudit.exe`ï¼WinSW 2.12.0 x64 èªå å«ï¼ | æ ï¼èªå¸¦ .NET 6 è¿è¡æ¶ï¼ | | Win7 SP1 / Server 2008 R2 / Server 2012(R2) | å è¯å å èªå å«çï¼Win7 é KB2533623ï¼ï¼æ¥ `api-ms-win-*.dll` ç¼ºå¤±æ¶æ¢ `WinSW.NET461.exe` æ¹åæ `trafficAudit.exe` | .NET Framework 4.6.1+ | | 32 ä½ç³»ç» | `WinSW-x86.exe` æ¹åæ `trafficAudit.exe` | æ ï¼èªå¸¦ .NET 6 è¿è¡æ¶ï¼ | ä¸è½½é¡µï¼<https://github.com/winsw/winsw/releases/tag/v2.12.0> ââ ä»»ä½æå»ºé½ç¨åä¸ä»½ `trafficAudit.xml`ï¼æ¹çåªæ¯å è£ å¨æä»¶åã `install-service.ps1` å¨ Windows PowerShell 2.0+ å¯ç¨ï¼`install-autostart.ps1` ç¨å° `New-ScheduledTask*`ï¼é Win8 / Server 2012 å以ä¸ã ### 5.5 è®¿é® æµè§å¨æå¼ `http://<é¨ç½²æºIP>:8090`ï¼å端已å åµï¼é¡µé¢ä¸æ¥å£åæºï¼æ é nginxï¼ï¼è´¦å· `admin / admin123`ã @@ -211,6 +251,10 @@ | æ°æ®åºè¿æ¥å¤±è´¥ | æ£æ¥ `application.yml`ï¼ç¡®è®¤ 5 个 SQL èæ¬å·²æ§è¡ | | å¯å¨æ¥ `Access denied ... (using password: NO)` | å端æ¿å°çåºå£ä»¤æ¯**空串**ï¼jar å ç½® `${TRAFFIC_DB_PASSWORD:}` æªè¢«å¤ç½®é ç½®è¦çãæ `backend/application.yml` æ¾å¨ jar å级并填 `spring.datasource.password`ï¼æè®¾ç¯å¢åé `TRAFFIC_DB_PASSWORD`ï¼æ¹å®éå¯ï¼æ ééæå | | 端å£å ç¨ | æ¹ `server.port`ï¼å端å¼åç«¯å£ 8080 | | æå¡å·²æ³¨åä½ 8090 æä¸å¼ | ç `backend\logs\trafficAudit.err.log`ï¼æå¡æ¹å¼è¯»çæ¯ `backend\application.yml`ï¼`password` å¿ é¡»æ¯çå®å£ä»¤ | | æå¡æ¥âæç»è®¿é®â/åä¸äºæ¥å¿ | é¨ç½²ç®å½æéä¸è¶³ï¼æ¢å° `D:\trafficAudit` è¿ç±»ç®åè·¯å¾ï¼æç» LocalSystem æåæé | | 䏿³å¼æºèªå¯ä½ä¿çæå¡ | `Set-Service TrafficAuditBackend -StartupType Manual` | | Win7/2008R2 䏿å¡å¯ä¸äºï¼æ¥ `api-ms-win-*.dll`ï¼ | è§ 5.4ãæä½ç³»ç»å ¼å®¹æ§ãï¼æ `WinSW.NET461.exe` æ¹åæ `trafficAudit.exe` æ¿æ¢ | ## åãå¼åç¯å¢æ¥å¸¸å¯å¨ @@ -222,6 +266,7 @@ ## åä¸ãåæ´è®°å½ - **2026-10-03**ï¼`pack-deploy.ps1` è¡¥é½å¤ç½® `application.yml`/`docs`/`db`/å¯å¨èæ¬å¹¶åæ¥ `backend\web`ï¼ä¿® `Access denied ... (using password: NO)`ï¼ï¼æ¨¡æ¿ç«¯å£ 8080â8090ï¼æ°å¢ Windows æå¡æ¹å¼å¼æºèªå¯ï¼WinSW 2.12.0 `trafficAudit.exe` + `trafficAudit.xml` + `install-service.ps1`ï¼èªå¨/å»¶è¿å¯å¨ã失败éå¯ãæ¥å¿æ»å¨ï¼ï¼è®¡å任塿¹å¼é为å¤éï¼è¡¥æä½ç³»ç»å ¼å®¹æ§è¯´æã - **2026-09-13**ï¼æ°å¢ä¸é®æå èæ¬ `package-deploy.py`ï¼jar æ¹ä¸ºå åµå端ï¼é¨ç½²æºä¸åéè¦ nginxï¼ï¼å é¤ Redis ç¸å ³è¯´æï¼ä»£ç æªä½¿ç¨ï¼ï¼è¡¥ `sql_wyc.sql` ä¸ `summary.template-dir`ï¼è¡¥ `jwt.secret` åå¼è§åï¼è¡¥é¨ç½²åéªè¯æ¸ åã - 2026-08-27ï¼é¦çï¼zip é¨ç½²å + nginx æ¹æ¡ï¼ã @@ -272,14 +317,17 @@ 1. ç¨ `deploy-templates/jar-application.yml`ï¼å ¨å ä½ç¬¦ï¼ä¸´æ¶æ¿æ¢æºç `application.yml`ï¼å `mvn clean package -DskipTests`ï¼æå»ºåèªå¨è¿åå¼åæºçå®é ç½®ï¼ 2. **è§£å jar èªæ£**ï¼æ£æ¥ `BOOT-INF/classes/application.yml` æ¯å¦å ¨ä¸ºå ä½ç¬¦ââ䏿¦åç° `sk-` æææå£ä»¤**ç´æ¥ä¸æ¢æå **ï¼ 3. `npm run build` é建å端 `dist`ï¼ 4. æ `deploy-templates/` ç»è£ 宿´é¨ç½²å ï¼backend / frontend / db / README-é¨ç½²è¯´æ.txtï¼ââ`backend/` å« jarã`application.yml`ãå¯å¨èæ¬ã`docs/`ã`web/`ï¼ç± dist èªå¨åæ¥ï¼ä¾ 8090 åç«¯å£æ¨¡å¼ï¼ï¼è¾åºå° `<OutRoot>\traffic-audit-deploy-<yyyyMMdd>`ï¼ 4. æ `deploy-templates/` ç»è£ 宿´é¨ç½²å ï¼backend / frontend / db / README-é¨ç½²è¯´æ.txtï¼ââ`backend/` å« jarã`application.yml`ãå¯å¨èæ¬ã`docs/`ã`web/`ï¼ç± dist èªå¨åæ¥ï¼ä¾ 8090 åç«¯å£æ¨¡å¼ï¼ï¼ä»¥å Windows æå¡ä¸ä»¶å¥ `trafficAudit.exe` + `trafficAudit.xml` + `install-service.ps1`ï¼è¾åºå° `<OutRoot>\traffic-audit-deploy-<yyyyMMdd>`ï¼ WinSW ä¼å ç¨ `deploy-templates\tools\winsw.exe` ç¼åï¼æ ¡éª SHA-256ï¼ï¼ç¼å缺失æåå¸ä¸ç¬¦æ¶èªå¨ä» GitHub 宿¹åå¸é¡µä¸è½½ v2.12.0 x64ï¼è¯¥äº§ç©æªå Authenticode ç¾åï¼å æ¤ä»¥åºå® SHA-256 ä½å®æ´æ§æ ¡éªï¼ï¼ 5. 对ç»è£ åçæ´å åæ«ä¸éææå¯é¥ã å¯éåæ°ï¼`-OutRoot` æå®è¾åºç®å½ï¼é»è®¤ä»åº `deploy\`ï¼ã`-SkipFrontend` å¤ç¨ç°æ distã`-SkipBackend` å¤ç¨ç°æ jarï¼åªéç»å ãä¸éç¼è¯ï¼ç¨äºå¿«éè¡¥å ï¼ã å¯éåæ°ï¼`-OutRoot` æå®è¾åºç®å½ï¼é»è®¤ä»åº `deploy\`ï¼ã`-SkipFrontend` å¤ç¨ç°æ distã`-SkipBackend` å¤ç¨ç°æ jarï¼åªéç»å ãä¸éç¼è¯ï¼ç¨äºå¿«éè¡¥å ï¼ã`-SkipServiceWrapper` 䏿 WinSW æå¡å è£ å¨æè¿å ï¼å³ä¸è¦âæ³¨åæ Windows æå¡âç弿ºèªå¯ï¼ã > è®°å½ï¼2026-10-03ï¼ï¼æ¤åæå·¥äº§åºç 10-02 å åªæ jar+web+distï¼ç¼º `application.yml`/`docs`/`db`/å¯å¨èæ¬ï¼é¨ç½²æºå¯å¨æ¥ `Access denied ... (using password: NO)`ãç°å·²ç±èæ¬èªå¨è¡¥é½è¿äºæä»¶å¹¶å¨æå åæ¿æ¢å ä½ç¬¦é ç½®ã æ¨¡æ¿ä»¶ç»ä¸æ¾å¨ **`deploy-templates/`**ï¼å·²å ¥åºï¼ï¼å¤é¨ `application.yml`ã`start-backend.cmd/.sh`ã`nginx.conf.example`ã`db\{init.sql,sql_city_bus,sql_city_taxi,sql_wyc}.sql`ã`README-é¨ç½²è¯´æ.txt`ãæ¹æ¨¡æ¿å³æ¹æå 产ç©ã 模æ¿ä»¶ç»ä¸æ¾å¨ **`deploy-templates/`**ï¼å·²å ¥åºï¼ï¼å¤é¨ `application.yml`ã`start-backend.cmd/.sh`ã`trafficAudit.xml`ã`install-service.ps1`ã`start-backend-service.cmd`ã`install-autostart.ps1`ã`nginx.conf.example`ã`db\{init.sql,sql_city_bus,sql_city_taxi,sql_wyc}.sql`ã`README-é¨ç½²è¯´æ.txt`ãæ¹æ¨¡æ¿å³æ¹æå 产ç©ã > `deploy-templates\tools\`ï¼WinSW äºè¿å¶ï¼17.4MBï¼**ä¸å ¥åº**ï¼å·²å `.gitignore`ï¼ï¼ç±æå èæ¬æéä¸è½½å¹¶æ ¡éª SHA-256ã ### è½®æ¢å¯é¥ååæ¥æ¬æº pack-deploy.ps1
@@ -9,7 +9,9 @@ æ§è¡ mvn clean packageï¼æ 论æè´¥é½è¿åå¼åæºçå®é ç½® 2) è§£å jar æ£æ¥å ç½® application.ymlï¼å¿ é¡»å ¨æ¯å ä½ç¬¦ï¼ç¦æ¢ sk- å¯é¥ / ææå£ä»¤ï¼ï¼ä¸åæ ¼ç´æ¥ä¸æ¢ 3) npm run build é建å端 distï¼å¯ -SkipFrontendï¼ 4) ç»è£ 宿´é¨ç½²å ï¼backend(jar + application.yml + å¯å¨èæ¬ + docs + web) / frontend/dist / db / README 4) ç»è£ 宿´é¨ç½²å ï¼backend(jar + application.yml + å¯å¨èæ¬ + æå¡å è£ å¨ + docs + web) / frontend/dist / db / README Windows æå¡å è£ å¨ WinSWï¼ä¼å ç¨ deploy-templates\tools\winsw.exe ç¼åï¼æ ¡éª SHA-256ï¼ï¼ 缺失æ¶èªå¨ä¸è½½ v2.12.0 x64 å°è¯¥ç¼åç®å½ï¼éå è¾åºä¸º backend\trafficAudit.exe 5) 对ç»è£ åçæ´å åæ«ä¸éææå¯é¥ ä¿®è®¢èæ¯ï¼2026-10-03ï¼ï¼2026-10-02 æå·¥äº§åºçå 缺 application.yml / docs / db / å¯å¨èæ¬ï¼ @@ -20,7 +22,8 @@ param( [string]$OutRoot = '', [switch]$SkipFrontend, [switch]$SkipBackend # å¤ç¨å·²åå¨ç jarï¼ä¸éç¼è¯ãä¸å¨æºç é ç½®ï¼ï¼ä» ç¨äºè¡¥å ¨/éç»åå¸å [switch]$SkipBackend, # å¤ç¨å·²åå¨ç jarï¼ä¸éç¼è¯ãä¸å¨æºç é ç½®ï¼ï¼ä» ç¨äºè¡¥å ¨/éç»åå¸å [switch]$SkipServiceWrapper # 䏿 WinSW æå¡å è£ å¨æè¿å ï¼å³ä¸æä¾âæ³¨åæ Windows æå¡âç弿ºèªå¯ï¼ ) $ErrorActionPreference = 'Stop' @@ -117,6 +120,40 @@ } if (-not (Test-Path $webDist)) { throw "æªæ¾å°å端产ç©ï¼$webDistï¼å»æ -SkipFrontend éæ°æå»ºï¼" } # ---------- WinSWï¼Windows æå¡å è£ å¨ï¼åå¤ï¼æ¬å°ç¼åä¼å ï¼ç¼ºå¤±æ¶ä»å®æ¹åå¸é¡µä¸è½½å¹¶æ ¡éª SHA-256 ---------- # WinSW v2.12.0 宿¹äº§ç©æªå Authenticode ç¾åï¼æä»¥ä»¥åºå® SHA-256 ä½ä¸ºå®æ´æ§æ ¡éªã $winswUrl = 'https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe' $winswSha256 = '05B82D46AD331CC16BDC00DE5C6332C1EF818DF8CEEFCD49C726553209B3A0DA' $winswSrc = Join-Path $tplDir 'tools\winsw.exe' function Test-WinswCache { param([string]$Path) if (-not (Test-Path -LiteralPath $Path)) { return $false } $hash = (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash if ($hash -ne $winswSha256) { Write-Host (' è¦åï¼WinSW ç¼å SHA-256 ä¸å¹é ï¼å°éæ°ä¸è½½ï¼ææ {0}...ï¼å®é {1}...ï¼' -f $winswSha256.Substring(0, 12), $hash.Substring(0, 12)) return $false } return $true } if ($SkipServiceWrapper) { Write-Host ' å·²æ -SkipServiceWrapper è·³è¿ï¼å å ä¸å« Windows æå¡æ¹å¼å¼æºèªå¯' } else { if (-not (Test-WinswCache $winswSrc)) { New-Item -ItemType Directory -Force -Path (Split-Path -Parent $winswSrc) | Out-Null Write-Host ' ä¸è½½ WinSW v2.12.0 x64 ...' try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri $winswUrl -OutFile $winswSrc -UseBasicParsing } catch { throw ("ä¸è½½ WinSW 失败ï¼{0}ã`n请æå¨ä¸è½½ {1} å为 {2} åéè¯ï¼æç¨ -SkipServiceWrapper è·³è¿ã" -f $_.Exception.Message, $winswUrl, $winswSrc) } if (-not (Test-WinswCache $winswSrc)) { throw "WinSW æ ¡éªå¤±è´¥ï¼å·²ä¸æ¢æå ï¼$winswSrc" } } Write-Host (' WinSW 就绪ï¼SHA-256 å·²æ ¡éªï¼ï¼{0:N1} MB' -f ((Get-Item -LiteralPath $winswSrc).Length / 1MB)) } # ---------- [4/5] ç»è£ 宿´é¨ç½²ç®å½ ---------- Write-Host '[4/5] ç»è£ é¨ç½²ç®å½...' $stamp = Get-Date -Format 'yyyyMMdd' @@ -129,6 +166,14 @@ Copy-Item (Join-Path $tplDir 'backend\application.yml') (Join-Path $dest 'backend') -Force Copy-Item (Join-Path $tplDir 'backend\start-backend.cmd') (Join-Path $dest 'backend') -Force Copy-Item (Join-Path $tplDir 'backend\start-backend.sh') (Join-Path $dest 'backend') -Force Copy-Item (Join-Path $tplDir 'backend\start-backend-service.cmd') (Join-Path $dest 'backend') -Force Copy-Item (Join-Path $tplDir 'backend\install-autostart.ps1') (Join-Path $dest 'backend') -Force if (-not $SkipServiceWrapper) { # WinSW è¦æ±é ç½®æä»¶åä¸ exe ååï¼trafficAudit.exe 读åç®å½ç trafficAudit.xml 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 $webDist (Join-Path $dest 'frontend') -Recurse -Force Copy-Item (Join-Path $tplDir 'frontend\nginx.conf.example') (Join-Path $dest 'frontend') -Force Copy-Item (Join-Path $tplDir 'db\*.sql') (Join-Path $dest 'db') -Force