Merge branch 'fix/lsphp-keep-listen'
Cloud Apache Container / Shell-Checks (push) Successful in 9s
Cloud Apache Container / Build-and-Push (74) (push) Successful in 1m39s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 1m28s
Cloud Apache Container / Build-and-Push (81) (push) Successful in 1m27s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 1m27s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 1m29s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 1m27s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 1m28s
Cloud Apache Container / Build-FPM-Images (74) (push) Successful in 1m29s
Cloud Apache Container / Build-FPM-Images (80) (push) Successful in 1m29s
Cloud Apache Container / Build-FPM-Images (81) (push) Successful in 1m26s
Cloud Apache Container / Build-FPM-Images (82) (push) Successful in 1m31s
Cloud Apache Container / Build-FPM-Images (83) (push) Successful in 1m27s
Cloud Apache Container / Build-FPM-Images (84) (push) Successful in 2m24s
Cloud Apache Container / Build-FPM-Images (85) (push) Successful in 1m27s
Cloud Apache Container / Build-LiteSpeed-Images (81) (push) Successful in 37s
Cloud Apache Container / Build-LiteSpeed-Images (82) (push) Successful in 35s
Cloud Apache Container / Build-LiteSpeed-Images (83) (push) Successful in 35s
Cloud Apache Container / Build-LiteSpeed-Images (84) (push) Successful in 33s
Cloud Apache Container / Build-LiteSpeed-Images (85) (push) Successful in 35s
Cloud Apache Container / Build-LSPHP-Images (81) (push) Successful in 1m1s
Cloud Apache Container / Build-LSPHP-Images (82) (push) Successful in 1m3s
Cloud Apache Container / Build-LSPHP-Images (83) (push) Successful in 1m1s
Cloud Apache Container / Build-LSPHP-Images (84) (push) Successful in 57s
Cloud Apache Container / Build-LSPHP-Images (85) (push) Successful in 57s
Cloud Apache Container / Build-Shared-httpd (push) Successful in 34s
Cloud Apache Container / Build-Shared-OLS (push) Successful in 31s

This commit is contained in:
2026-08-13 15:03:49 -07:00
+27 -1
View File
@@ -109,6 +109,32 @@ export PHP_LSAPI_MAX_REQUESTS="${PHP_LSAPI_MAX_REQUESTS:-500}"
export LSAPI_MAX_IDLE="${LSAPI_MAX_IDLE:-30}" export LSAPI_MAX_IDLE="${LSAPI_MAX_IDLE:-30}"
export LSAPI_EXTRA_CHILDREN="${LSAPI_EXTRA_CHILDREN:-5}" export LSAPI_EXTRA_CHILDREN="${LSAPI_EXTRA_CHILDREN:-5}"
export LSAPI_AVOID_FORK="${LSAPI_AVOID_FORK:-0}" export LSAPI_AVOID_FORK="${LSAPI_AVOID_FORK:-0}"
## LSAPI_KEEP_LISTEN=2 works around a leak in lsphp's own bookkeeping — not a
## setting we're tuning for taste. The master keeps a `busy` worker counter in
## a MAP_SHARED page it shares with its children; measured live on whp01,
## that counter drifts NEGATIVE over days of uptime (arclightcourt.com-01 was
## at busy=-8 after 6.9 days; a healthy sibling sat at 0..9). php-src
## sapi/litespeed/lsapilib.c computes each child's idle-exit grace period as
## `10 + busy*10` seconds (capped by LSAPI_MAX_IDLE) INSIDE
## `if (s_keep_listener == 1)` — with busy=-8 that's `wait_time = -70`, so
## workers exit after ~1s idle instead of 10-30s. No worker then lingers in
## accept(), so the master's "an idle worker is already accepting, don't
## fork" guard never fires and it forks for every single connection —
## observed slamming the hard child ceiling under bot traffic
## (`Reached max children process limit`) and, on rejection, leaving the
## pending connection to rot in the kernel backlog as a 503. Confirmed
## asymmetry: the affected site logged 306 OLS-side `ExtConn timed out` /
## deadlock / `oops! 503` errors where an identically-configured healthy
## sibling logged 0. Restarting the container resets the counter to 0 (it's
## initialised at master start) but it drifts negative again over about a
## week — a reset, not a cure. LSAPI_KEEP_LISTEN=2 skips the `== 1` branch
## entirely, so idle-exit timing is never derived from the leaked counter and
## instead falls straight back to LSAPI_MAX_IDLE above. The is_enough_free_mem()
## memory guard sits immediately above that branch in lsapilib.c and is NOT
## part of it, so it still applies at =2 — this does not trade away the
## memory-pressure protection LSAPI_MAX_IDLE exists for. Still overridable
## (e.g. back to 1) per-container as an escape hatch.
export LSAPI_KEEP_LISTEN="${LSAPI_KEEP_LISTEN:-2}"
LSPHP_BIND="${LSPHP_BIND:-0.0.0.0:9000}" LSPHP_BIND="${LSPHP_BIND:-0.0.0.0:9000}"
## ---- .user.ini support ---- ## ---- .user.ini support ----
@@ -130,7 +156,7 @@ LSPHP_BIND="${LSPHP_BIND:-0.0.0.0:9000}"
## .user.ini has not been remediated yet. ## .user.ini has not been remediated yet.
export LSPHP_ENABLE_USER_INI="${LSPHP_ENABLE_USER_INI:-on}" export LSPHP_ENABLE_USER_INI="${LSPHP_ENABLE_USER_INI:-on}"
echo "Container memory: ${CONTAINER_MEMORY_MB}MB | PHP_LSAPI_CHILDREN=${PHP_LSAPI_CHILDREN} | LSAPI_MAX_IDLE=${LSAPI_MAX_IDLE} | PHPVER=${PHPVER} | bind=${LSPHP_BIND} | user_ini=${LSPHP_ENABLE_USER_INI}" echo "Container memory: ${CONTAINER_MEMORY_MB}MB | PHP_LSAPI_CHILDREN=${PHP_LSAPI_CHILDREN} | LSAPI_MAX_IDLE=${LSAPI_MAX_IDLE} | LSAPI_KEEP_LISTEN=${LSAPI_KEEP_LISTEN} | PHPVER=${PHPVER} | bind=${LSPHP_BIND} | user_ini=${LSPHP_ENABLE_USER_INI}"
## Validate a numeric value destined for a generated php.ini fragment. ## Validate a numeric value destined for a generated php.ini fragment.
## Sets INI_NUM to the value when it is acceptable, and to "" (plus a WARNING) ## Sets INI_NUM to the value when it is acceptable, and to "" (plus a WARNING)