2025-08-19 18:15:31 +08:00
@ echo off
chcp 65001 > nul
2025-08-26 15:43:47 +08:00
setlocal enabledelayedexpansion
: : version: 0.13
2025-08-19 18:15:31 +08:00
2025-08-26 15:43:47 +08:00
: : ===================================================================== 主逻辑顺序
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: : 初始化脚本.
call : INITIALIZE
: : 调用主函数.
goto : main > nul
exit /b 0
2025-08-19 18:15:31 +08:00
2025-08-26 15:43:47 +08:00
: INITIALIZE
set " SCRIPT_PATH= %~dp0 "
set " SCRIPT_NAME= %~nx0 "
set " SCRIPT_NAME_WITHOUT_EXT= %~n0 "
set " LOG_LEVEL_THRESHOLD=DEBUG "
call : get_current_time
set " CALL_TIME=!CURRENT_TIME! "
call : LOG_INFO " Startup %SCRIPT_NAME% : %CALL_TIME% "
set " SHOW_TITLE=true "
for %% a in ( %* ) do ( if /i " %% a " == " /notitle " set set " SHOW_TITLE=false " )
if " !SHOW_TITLE! " == " true " ( title %SCRIPT_NAME% )
2025-08-19 23:48:37 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: CHECK_IS_ADMIN
net session > nul 2 >& 1
if %errorLevel% neq 0 (
exit /b 1
)
exit /b 0
: MD52String
setlocal
set " input= %~1 "
for /f " delims= " %% i in ( '
powershell -Command " [System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider).ComputeHash([System.Text.Encoding]::UTF8.GetBytes('!input!'))).Replace('-','').ToLower() "
') do set " md5= %% i "
endlocal & set " md5= %md5% "
2025-08-19 23:48:37 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: MD5Hash2File
setlocal
set " input_text= %~1 "
set " return_var= %~2 "
where md5sum > nul 2 > nul
if errorlevel 1 (
echo Error: md5sum command not found in PATH
endlocal
exit /b 1
)
set " temp_file= %TEMP% \md5_ %RANDOM% .txt "
echo !input_text! > " !temp_file! "
for /f " tokens=1 " %% i in ( 'md5sum "!temp_file!" 2^>nul' ) do (
set " hash_result= %% i "
2025-08-20 16:00:41 +08:00
)
2025-08-26 15:43:47 +08:00
if " !hash_result! " == " " (
echo Error: Failed to calculate MD5 hash
del " !temp_file! " 2 > nul
endlocal
exit /b 2
)
del " !temp_file! " 2 > nul
endlocal & set " %return_var% = %hash_result% "
exit /b 0
: GET_TIME_STAMP
setLocal
set " level= %~1 "
if /i " %level% " == " ms " (
for /f %% i in ( 'powershell -command "[math]::Truncate([decimal]((Get-Date).ToUniversalTime() - [datetime]'1970-01-01' ) .TotalMilliseconds) " ') do set timestamp_ms= %% i
if %errorlevel% == 0 (
set " timestamp=!timestamp_ms! "
)
)
if /i " %level% " == " s " (
for /f %% i in ( 'powershell -command "[math]::Truncate([decimal]((Get-Date).ToUniversalTime() - [datetime]'1970-01-01' ) .TotalSeconds) " ') do set timestamp_s= %% i
if %errorlevel% == 0 (
set " timestamp=!timestamp_s! "
)
)
endLocal & set " timestamp= %timestamp% "
2025-08-19 23:48:37 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: GET_DATE_TIME
for /f " tokens=2-4 delims=/ " %% a in ( 'date /t' ) do ( set __date = %% a-%% b-%% c)
for /f " tokens=1-2 delims=/: " %% a in ( 'time /t' ) do ( set __time = %% a%% b)
set " CURRENT_DATE_TIME= %__date% _ %__time% "
exit /b 0
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
: GET_CURRENT_TIME
for /f " tokens=2 delims== " %% a in ( 'wmic OS Get localdatetime /value' ) do set " datetime= %% a "
set " CURRENT_TIME= %datetime:~0,4% - %datetime:~4,2% - %datetime:~6,2% %datetime:~8,2% : %datetime:~10,2% : %datetime:~12,2% "
exit /b 0
: GET_CURRENT_DATE
for /f " tokens=2 delims== " %% a in ( 'wmic OS Get localdatetime /value' ) do set " datetime= %% a "
set " CURRENT_DATE= %datetime:~0,4% %datetime:~4,2% %datetime:~6,2% "
exit /b 0
: WAIT
set /a " SECOND= %~1 "
timeout /t %SECOND% /nobreak > nul
exit /b 0
: LOG
setLocal
set " LOG_LEVEL= %~1 "
set LOG_MESSAGE =
shift
: log__params_loop
if not " %~1 " == " " (
set " LOG_MESSAGE= %LOG_MESSAGE% %~1 "
shift
goto log__params_loop
2025-08-21 12:10:46 +08:00
)
2025-08-26 15:43:47 +08:00
call : get_log_level_num " %LOG_LEVEL% " " CALLER_LEVEL_NUM "
call : get_log_level_num " %LOG_LEVEL_THRESHOLD% " " THRESHOLD_LEVEL_NUM "
if %CALLER_LEVEL_NUM% lss %THRESHOLD_LEVEL_NUM% (
endLocal
exit /b 0
)
call : GET_CURRENT_TIME
if /i " %LOG_LEVEL% " == " GROUP " echo .
echo [%CURRENT_TIME% ] - [%LOG_LEVEL% ] - %LOG_MESSAGE%
endLocal
exit /b 0
: get_log_level_num
setLocal
set " level= %~1 "
set " num=0 "
if /i " %level% " == " TRACE " set " num=1 "
if /i " %level% " == " DEBUG " set " num=2 "
if /i " %level% " == " INFO " set " num=3 "
if /i " %level% " == " WARN " set " num=4 "
if /i " %level% " == " GROUP " set " num=5 "
if /i " %level% " == " ERROR " set " num=6 "
endLocal & set " %~2 = %num% "
exit /b 0
: LOG_ERROR
call : LOG ERROR %* && exit /b 0
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
: LOG_GROUP
call : LOG GROUP " =============================== " %* " =============================== "
2025-08-21 12:10:46 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: LOG_WARN
call : LOG WARN %* && exit /b 0
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: LOG_INFO
call : LOG INFO %* && exit /b 0
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: LOG_DEBUG
call : LOG DEBUG %* && exit /b 0
2025-08-19 18:15:31 +08:00
2025-08-26 15:43:47 +08:00
: LOG_DEBUG
call : LOG DEBUG %* && exit /b 0
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: LOG_TRACE
call : LOG TRACE %* && exit /b 0
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: GET_STRING_LENGTH
setlocal
set " input_str= %~1 "
set " str_length= %~2 "
: get_string_length_loop
if defined input_str (
set /a str_length += 1
set " input_str=!input_str:~1! "
goto get_string_length_loop
)
endlocal & (
if not " %~2 " == " " (
set " %~2 = %str_length% "
) else (
exit /b %str_length%
)
)
exit /b 0
2025-08-19 23:48:37 +08:00
2025-08-26 15:43:47 +08:00
: GET_STRING_LENGTH_WITHOUT_SPACES
setlocal
set " input_str= %~1 "
set " result_var= %~2 "
set " tmp_char=!input_str! "
set /a str_length = 0
for %% p in ( 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 ) do (
if not " !tmp_char:~ %% p! " == " " (
set " tmp_char=!tmp_char:~ %% p! "
set /a str_length +=%% p
)
)
if not " !tmp_char! " == " " set /a str_length += 1
call : LOG_TRACE Length=%str_length% String=%input_str%
endlocal & (
if not " %~2 " == " " (
set " %~2 = %str_length% "
) else (
exit /b %str_length%
)
)
2025-08-19 23:48:37 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: RANDOM_STR
setlocal
set " len= %~1 "
set " varname= %~2 "
if " !varname! " == " " set " varname=RAND_STR "
set " chars=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
set " random_str= "
call : GET_STRING_LENGTH " %chars% " " charts_length "
for /l %% i in ( 1 ,1 ,!len! ) do (
set /a rand_index =! random! %% !charts_length !
call set " char= %% chars:~!rand_index!,1 %% "
set " random_str=!random_str!!char! "
)
endlocal & set " %varname% = %random_str% "
2025-08-20 16:00:41 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: GET_SINGLE_PID_BY_PORT
setlocal
call : RandomStr single_pid_tmp
call : LOG_INFO netstat -ano ^| grep -E " : %1 " ^| grep " LISTENING " ^| awk " {print $NF} " ^| head -n 1
netstat -ano | grep -E " : %1 " | grep " LISTENING " | awk " {print $NF} " | head -n 1 > %single_pid_tmp% .txt
set /p pid = < %single_pid_tmp% .txt
call : LOG_INFO pid: %pid%
del %single_pid_tmp% .txt
endlocal & set pid = %pid%
exit /b 0
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
: GET_USED_PID_BY_PORT
setlocal
set " PORT= %~1 "
set /a " UNIQUE_COUNT=0 "
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
if " !PORT! " == " " (
call : log_error ERROR: Port number required
endlocal & exit /b 0
)
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
set " TEMP_FILE= %TEMP% \port_ %PORT% _ %RANDOM% _ %TIME::=_% .tmp "
set " PID_LIST_FILE= %TEMP% \pids_ %PORT% _ %RANDOM% .tmp "
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
call : LOG_INFO Checking for processes using port !PORT! ...
netstat -ano | grep -E " :!PORT! " > " !TEMP_FILE! "
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
if !errorlevel! neq 0 (
call : LOG_INFO No process found using port !PORT!
del " !TEMP_FILE! " 2 > nul
endlocal & exit /b 0
2025-08-20 16:00:41 +08:00
)
2025-08-26 15:43:47 +08:00
echo . > " !PID_LIST_FILE! "
2025-08-20 16:00:41 +08:00
echo .
2025-08-26 15:43:47 +08:00
call : LOG_GROUP Processes using port !PORT!
for /f " tokens=5 " %% a in ( !TEMP_FILE! ) do (
set " PID= %% a "
: : grep -E "^^!PID! $" "!PID_LIST_FILE!" >nul
findstr /x " !PID! " " !PID_LIST_FILE! " > nul
if !errorlevel! neq 0 (
echo !PID! >> " !PID_LIST_FILE! "
set /a " UNIQUE_COUNT+=1 "
call : LOG_INFO [!UNIQUE_COUNT!] PID: !PID!
set " PROCESS_NAME= "
set " SESSION_NAME= "
set " SESSION_NUM= "
set " MEM_USAGE= "
for /f " tokens=1,2,3,4,5* " %% b in ( 'tasklist /fi "PID eq !PID!" /fo table ^| findstr /i "!PID!"' ) do (
if not " %% b " == " = " if not " %% b " == " Image " (
call : LOG_INFO " PROCESS_NAME= %% b "
call : LOG_INFO " PID_VALUE= %% c "
call : LOG_INFO " SESSION_NAME= %% d "
call : LOG_INFO " SESSION_NUM= %% e "
call : LOG_INFO " MEM_USAGE= %% f "
)
)
if not " !PROCESS_NAME! " == " " (
call : LOG_INFO Process: !PROCESS_NAME!
call : LOG_INFO Memory: !MEM_USAGE!
)
echo .
)
)
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
if !UNIQUE_COUNT! gtr 0 (
call : LOG_GROUP PIDs using port !PORT!
: : type "!PID_LIST_FILE!"
call : LOG_INFO Total: !UNIQUE_COUNT! process
)
2025-08-20 16:00:41 +08:00
2025-08-26 15:43:47 +08:00
del " !TEMP_FILE! " 2 > nul
del " !PID_LIST_FILE! " 2 > nul
2025-08-20 16:00:41 +08:00
endlocal & exit /b %UNIQUE_COUNT%
2025-08-26 15:43:47 +08:00
: LISTEN_PORT_LIST
call : listen_port_list__default_set
set all_ports_up = 1
for %% i in ( %PORT_LIST% ) do (
for /f " tokens=1,2 delims=: " %% a in ( " %% i " ) do (
set port = %% a
set service = %% b
netstat -an | find " : %% a " > nul
if !errorlevel! neq 0 (
set all_ports_up = 0
call : LOG_DEBUG " !service! Server (Port: %% a) isn't ready... "
)
2025-08-21 12:10:46 +08:00
)
)
2025-08-26 15:43:47 +08:00
if !all_ports_up! equ 1 (
call : DISPLAY_SUCCESS && exit /b 0
)
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
set /a COUNTER += CHECK_INTERVAL
if !COUNTER! geq %MAX_WAIT% (
call : LOG_ERROR " Services did not start within !COUNTER! seconds " && exit /b 1
)
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
call : LOG_DEBUG " Waiting for services... (!COUNTER!/ %MAX_WAIT% seconds) "
echo .
call : WAIT %CHECK_INTERVAL%
goto LISTEN_PORT_LIST
: listen_port_list__default_set
set CHECK_INTERVAL = 5
set MAX_WAIT = 90
set COUNTER = 0
exit /b 0
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
: DISPLAY_SUCCESS
call : WAIT 3
echo .
echo ========================================
echo %SERVER_HUMP% Services Successfully Started
echo ========================================
for %% i in ( %PORT_LIST% ) do (
for /f " tokens=1,2 delims=: " %% a in ( " %% i " ) do (
echo - %% b Server - Port %% a is listening
)
)
echo ========================================
echo .
exit /b 0
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
: AUTOSTART
setlocal
set DESCRIPTION = %~1
set SCRIPT_PATH = %~2
set SCRIPT_FILE = %~3
set PARAMS =
shift /3
: autostart__params_loop
if not " %~1 " == " " (
set " PARAMS= %PARAMS% %~3 "
shift
goto autostart__params_loop
)
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
call : GET_STRING_LENGTH " %SCRIPT_PATH% " " len "
set /a " last_pos=len-1 "
for /f " delims= " %% c in ( " !SCRIPT_PATH:~ %last_pos% ,1! " ) do (
if not " %% c " == " \ " (
set " SCRIPT_PATH= %SCRIPT_PATH% \ "
)
)
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
call : START " %DESCRIPTION% " " %SCRIPT_PATH% " " %SCRIPT_FILE% " %PARAMS%
2025-08-21 12:10:46 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: START
setlocal
set DESCRIPTION = %~1
set SCRIPT_PATH = %~2
set SCRIPT_FILE = %~3
set PARAMS =
shift /3
: start__params_loop
if not " %~1 " == " " (
set " PARAMS= %PARAMS% %~3 "
shift
goto start__params_loop
)
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
call : LOG_DEBUG " %SCRIPT_PATH% %SCRIPT_FILE% "
if exist " %SCRIPT_PATH% %SCRIPT_FILE% " (
echo .
call : LOG_INFO " Starting %DESCRIPTION% ... "
cd /d " %SCRIPT_PATH% "
start " %DESCRIPTION% Startup " /B cmd /c " %SCRIPT_FILE% %PARAMS% "
if errorlevel 1 (
call : log_error %DESCRIPTION% start Failed.
pause && exit /b 1
)
) else (
call : log_error Startup file not found: %SCRIPT_PATH% \%SCRIPT_FILE%
pause && exit /b 1
)
endlocal
2025-08-21 12:10:46 +08:00
exit /b 0
2025-08-26 15:43:47 +08:00
: Exit
set " exit_code= %~1 "
set " error_msg= %~2 "
if " !exit_code! " == " " set " exit_code=0 "
if not " !error_msg! " == " " (
call : LOG_ERROR An error occurred^( !exit_code! ^) : !error_msg!
)
call : Cleanup
exit /b !exit_code!
: Cleanup
call : LOG_INFO Cleaning up resources ...
goto : EOF
2025-08-21 12:10:46 +08:00
2025-08-26 15:43:47 +08:00
: : ===================================================================== 主逻辑起点
: : 主函数.
2025-08-20 16:00:41 +08:00
: main
setlocal
2025-08-26 15:43:47 +08:00
call : LOG_INFO " 脚本开始执行 "
2025-08-20 16:00:41 +08:00
2025-08-21 12:10:46 +08:00
: : nginx
2025-08-26 15:43:47 +08:00
call : GET_USED_PID_BY_PORT 18080
2025-08-20 16:00:41 +08:00
if !ERRORLEVEL! neq 0 (
2025-08-26 15:43:47 +08:00
call : LOG_INFO Found !ERRORLEVEL! processes.
call : GET_SINGLE_PID_BY_PORT 18080
call : LOG_GROUP Killing Process !pid!
2025-08-20 16:00:41 +08:00
taskkill -f -im home-web.exe
)
timeout /t 1 /nobreak > nul
2025-08-26 15:43:47 +08:00
call : AUTOSTART " Nginx " " %SCRIPT_PATH% nginx " " home-web.exe " " -c " " conf/web.conf "
2025-08-20 16:00:41 +08:00
2025-08-21 12:10:46 +08:00
: : redis
2025-08-20 16:00:41 +08:00
timeout /t 3 /nobreak > nul
2025-08-26 15:43:47 +08:00
call : AUTOSTART " Redis " " %SCRIPT_PATH% redis " " redis-server.exe " " redis.conf "
2025-08-20 16:00:41 +08:00
2025-08-21 12:10:46 +08:00
: : minio
2025-08-20 16:00:41 +08:00
timeout /t 3 /nobreak > nul
2025-08-26 15:43:47 +08:00
call : AUTOSTART " MinIO " " %SCRIPT_PATH% io " " minio-server.bat "
2025-08-20 16:00:41 +08:00
2025-08-21 12:10:46 +08:00
: : rocketmq
2025-08-20 16:00:41 +08:00
timeout /t 3 /nobreak > nul
2025-08-26 15:43:47 +08:00
call : AUTOSTART " RocketMQ " " %SCRIPT_PATH% rocketmq\sbin " " rocketmq.bat "
2025-08-21 12:10:46 +08:00
set PORT_LIST = 9876:RocketMQ-NameServer 10911:RocketMQ-Broker 8081:RocketMQ-Proxy 8088:RocketMQ-Dashboard
set SERVER_HUMP = RocketMQ
2025-08-26 15:43:47 +08:00
call : LISTEN_PORT_LIST
2025-08-20 16:00:41 +08:00
endlocal
2025-08-26 15:43:47 +08:00
goto : Exit 0