From a02631a3fc8307c55140b80716edd09e662fc261 Mon Sep 17 00:00:00 2001
From: SajjadMahmoody <117562560+SajjadMahmoody@users.noreply.github.com>
Date: Sun, 19 Apr 2026 00:10:29 +0330
Subject: [PATCH] AboveNormal for all services
---
scripts/diagnose.bat | 78 ++++++++++++++++++++++++++
scripts/matab-autostart.xml | 1 +
scripts/matab-phpcgi.xml | 1 +
scripts/nginx/conf/nginx.conf | 20 ++++++-
scripts/nginx/conf/nginx.conf.template | 20 ++++++-
scripts/warmup.bat | 8 +--
6 files changed, 120 insertions(+), 8 deletions(-)
create mode 100644 scripts/diagnose.bat
diff --git a/scripts/diagnose.bat b/scripts/diagnose.bat
new file mode 100644
index 0000000..7f78c6c
--- /dev/null
+++ b/scripts/diagnose.bat
@@ -0,0 +1,78 @@
+@echo off
+setlocal EnableDelayedExpansion
+chcp 65001 >nul 2>&1
+
+echo.
+echo ============================================================
+echo Matab Startup Diagnostics
+echo ============================================================
+echo.
+
+REM --- [1] Service Status ---
+echo [1] Service Status:
+for %%S in (MatabPHPCgi MatabAutostart) do (
+ sc query %%S 2>nul | find "RUNNING" >nul
+ if !errorlevel! equ 0 (
+ echo %%S [RUNNING]
+ ) else (
+ sc query %%S 2>nul | find "STOPPED" >nul
+ if !errorlevel! equ 0 (
+ echo %%S [STOPPED]
+ ) else (
+ echo %%S [NOT INSTALLED]
+ )
+ )
+)
+echo.
+
+REM --- [2] Port Check ---
+echo [2] Port Availability:
+powershell -NoProfile -Command ^
+ "foreach($p in @(8000,9001)){try{$t=New-Object Net.Sockets.TcpClient;$t.Connect('127.0.0.1',$p);$t.Close();Write-Host (' Port ' + $p + ' [OPEN]')}catch{Write-Host (' Port ' + $p + ' [CLOSED]')}}"
+echo.
+
+REM --- [3] Nginx health (no PHP) ---
+echo [3] Nginx response time (no PHP):
+powershell -NoProfile -Command ^
+ "try{$sw=[Diagnostics.Stopwatch]::StartNew();$r=Invoke-WebRequest 'http://localhost:8000/nginx-health' -TimeoutSec 5 -UseBasicParsing -ErrorAction Stop;$sw.Stop();Write-Host (' ' + $sw.ElapsedMilliseconds + ' ms (status ' + $r.StatusCode + ')')}catch{Write-Host ' FAILED - nginx not responding'}"
+echo.
+
+REM --- [4] First PHP request timing ---
+echo [4] First PHP request time (cold = slow, warm = fast):
+powershell -NoProfile -Command ^
+ "$sw=[Diagnostics.Stopwatch]::StartNew(); try{ $r=Invoke-WebRequest 'http://localhost:8000/admin/login' -TimeoutSec 30 -UseBasicParsing -MaximumRedirection 5 -ErrorAction SilentlyContinue; $sw.Stop(); $ms=$sw.ElapsedMilliseconds; $label=if($ms -lt 800){'[FAST]'}elseif($ms -lt 3000){'[OK - warming up]'}else{'[SLOW - OPcache cold]'}; Write-Host (' ' + $ms + ' ms status=' + $r.StatusCode + ' ' + $label) }catch{ $sw.Stop(); Write-Host (' FAILED after ' + $sw.ElapsedMilliseconds + ' ms err=' + $_.Exception.Message) }"
+echo.
+
+REM --- [5] Second PHP request timing (should be faster) ---
+echo [5] Second PHP request time (OPcache should kick in):
+powershell -NoProfile -Command ^
+ "$sw=[Diagnostics.Stopwatch]::StartNew(); try{ $r=Invoke-WebRequest 'http://localhost:8000/admin/login' -TimeoutSec 30 -UseBasicParsing -MaximumRedirection 5 -ErrorAction SilentlyContinue; $sw.Stop(); $ms=$sw.ElapsedMilliseconds; $label=if($ms -lt 500){'[FAST - OPcache working]'}elseif($ms -lt 1500){'[OK]'}else{'[SLOW - problem]'}; Write-Host (' ' + $ms + ' ms status=' + $r.StatusCode + ' ' + $label) }catch{ $sw.Stop(); Write-Host (' FAILED after ' + $sw.ElapsedMilliseconds + ' ms err=' + $_.Exception.Message) }"
+echo.
+
+REM --- [6] PHP process count ---
+echo [6] PHP worker processes:
+powershell -NoProfile -Command ^
+ "$procs=Get-Process php-cgi -ErrorAction SilentlyContinue;if($procs){Write-Host (' ' + $procs.Count + ' php-cgi processes running (expected: 9 = 1 master + 8 children)')}else{Write-Host ' No php-cgi processes found!'}"
+echo.
+
+REM --- [7] OPcache file cache ---
+echo [7] OPcache file cache on disk:
+powershell -NoProfile -Command ^
+ "if(Test-Path 'C:\tmp\php-opcache'){$files=(Get-ChildItem 'C:\tmp\php-opcache' -Recurse -File -ErrorAction SilentlyContinue).Count;$size=[math]::Round((Get-ChildItem 'C:\tmp\php-opcache' -Recurse -File -ErrorAction SilentlyContinue|Measure-Object -Property Length -Sum).Sum/1MB,1);Write-Host (' ' + $files + ' files, ' + $size + ' MB cached')}else{Write-Host ' Directory not found (C:\tmp\php-opcache)'}"
+echo.
+
+REM --- [8] Warmup task status ---
+echo [8] MatabWarmup scheduled task:
+powershell -NoProfile -Command ^
+ "try{$t=Get-ScheduledTask -TaskName 'MatabWarmup' -ErrorAction Stop;$info=Get-ScheduledTaskInfo -TaskName 'MatabWarmup' -ErrorAction SilentlyContinue;$last=if($info.LastRunTime){$info.LastRunTime.ToString('yyyy-MM-dd HH:mm:ss')}else{'never'};Write-Host (' State: ' + $t.State + ' | Last run: ' + $last + ' | Last result: ' + $info.LastTaskResult)}catch{Write-Host ' Task not found - run install.bat'}"
+echo.
+
+echo ============================================================
+echo Interpretation:
+echo - If [4] ^> 3000ms and [5] ^< 1000ms: OPcache warming up normally
+echo - If both [4] and [5] are slow: PHP or DB issue
+echo - If port 9001 CLOSED: MatabPHPCgi service failed
+echo - If nginx-health fails but port 8000 open: nginx config error
+echo ============================================================
+echo.
+pause
diff --git a/scripts/matab-autostart.xml b/scripts/matab-autostart.xml
index f4e13ba..380e190 100644
--- a/scripts/matab-autostart.xml
+++ b/scripts/matab-autostart.xml
@@ -8,6 +8,7 @@
%BASE%\nginx
Tcpip
MatabPHPCgi
+ AboveNormal
diff --git a/scripts/matab-phpcgi.xml b/scripts/matab-phpcgi.xml
index 346a8bf..14a635c 100644
--- a/scripts/matab-phpcgi.xml
+++ b/scripts/matab-phpcgi.xml
@@ -9,6 +9,7 @@
Tcpip
+ AboveNormal
diff --git a/scripts/nginx/conf/nginx.conf b/scripts/nginx/conf/nginx.conf
index d9efb4f..e93b42a 100644
--- a/scripts/nginx/conf/nginx.conf
+++ b/scripts/nginx/conf/nginx.conf
@@ -35,9 +35,17 @@ http {
application/xml
image/svg+xml;
+ # FastCGI connection pool — reuse TCP connections to php-cgi instead of
+ # opening a new one per request (reduces latency on every PHP request)
+ upstream php_fpm {
+ server 127.0.0.1:9001;
+ keepalive 16;
+ }
+
server {
listen 8000;
- server_name localhost 127.0.0.1;
+ listen [::]:8000;
+ server_name localhost 127.0.0.1 ::1;
root "D:/git/matab-panel/public";
index index.php;
@@ -46,16 +54,24 @@ http {
open_file_cache_min_uses 2;
open_file_cache_errors on;
+ # Lightweight health-check endpoint — no PHP, used by warmup script
+ location = /nginx-health {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
- fastcgi_pass 127.0.0.1:9001;
+ fastcgi_pass php_fpm;
fastcgi_index index.php;
fastcgi_read_timeout 120;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
+ fastcgi_keep_conn on;
fastcgi_buffering on;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
diff --git a/scripts/nginx/conf/nginx.conf.template b/scripts/nginx/conf/nginx.conf.template
index 9d2a2c7..ee02032 100644
--- a/scripts/nginx/conf/nginx.conf.template
+++ b/scripts/nginx/conf/nginx.conf.template
@@ -35,9 +35,17 @@ http {
application/xml
image/svg+xml;
+ # FastCGI connection pool — reuse TCP connections to php-cgi instead of
+ # opening a new one per request (reduces latency on every PHP request)
+ upstream php_fpm {
+ server 127.0.0.1:9001;
+ keepalive 16;
+ }
+
server {
listen 8000;
- server_name localhost 127.0.0.1;
+ listen [::]:8000;
+ server_name localhost 127.0.0.1 ::1;
root "{{PUBLIC_DIR}}";
index index.php;
@@ -46,16 +54,24 @@ http {
open_file_cache_min_uses 2;
open_file_cache_errors on;
+ # Lightweight health-check endpoint — no PHP, used by warmup script
+ location = /nginx-health {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
- fastcgi_pass 127.0.0.1:9001;
+ fastcgi_pass php_fpm;
fastcgi_index index.php;
fastcgi_read_timeout 120;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
+ fastcgi_keep_conn on;
fastcgi_buffering on;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
diff --git a/scripts/warmup.bat b/scripts/warmup.bat
index f208749..850a85a 100644
--- a/scripts/warmup.bat
+++ b/scripts/warmup.bat
@@ -1,13 +1,13 @@
@echo off
setlocal EnableDelayedExpansion
-echo [Warmup] Waiting for Matab web server on port 8000...
+echo [Warmup] Waiting for nginx on port 8000...
powershell -NoProfile -Command ^
- "$ok=0; for($i=0;$i -lt 120;$i++){try{$t=New-Object Net.Sockets.TcpClient;$t.Connect('127.0.0.1',8000);$t.Close();$ok=1;break}catch{Start-Sleep -Milliseconds 500}}; if(!$ok){Write-Host '[Warmup] Timeout - server not ready.'; exit 1}"
+ "$ok=0; for($i=0;$i -lt 120;$i++){try{$r=(Invoke-WebRequest 'http://localhost:8000/nginx-health' -TimeoutSec 2 -UseBasicParsing -ErrorAction Stop).StatusCode; if($r -eq 200){$ok=1;break}}catch{Start-Sleep -Milliseconds 500}}; if(!$ok){Write-Host '[Warmup] Timeout - server not ready.'; exit 1}"
if %errorlevel% neq 0 exit /b 1
-echo [Warmup] Firing 10 parallel requests to warm up all 8 PHP workers...
+echo [Warmup] Firing parallel requests to warm up all 8 PHP workers...
powershell -NoProfile -Command ^
- "$urls='http://localhost:8000/','http://localhost:8000/matab/login'; $jobs=@(); 1..10|ForEach-Object{$u=$urls[($_ %% 2)]; $jobs+=Start-Job -ScriptBlock{param($u)try{Invoke-WebRequest $u -TimeoutSec 60 -UseBasicParsing -ErrorAction SilentlyContinue|Out-Null}catch{}} -ArgumentList $u}; $jobs|Wait-Job|Out-Null; $jobs|Remove-Job"
+ "$urls=@('http://localhost:8000/admin/login','http://localhost:8000/admin','http://localhost:8000/'); $jobs=@(); 1..16|ForEach-Object{$u=$urls[($_ %% $urls.Count)]; $jobs+=Start-Job -ScriptBlock{param($u)try{Invoke-WebRequest $u -TimeoutSec 60 -UseBasicParsing -ErrorAction SilentlyContinue|Out-Null}catch{}} -ArgumentList $u}; $jobs|Wait-Job|Out-Null; $jobs|Remove-Job"
echo [Warmup] PHP OPcache warmed up successfully.