Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WEB_CONCURRENCY auto-tuning: PHP memory_limit improvements, streamlined output, verbose mode #684

Merged
merged 8 commits into from
Jan 31, 2024

Conversation

dzuelke
Copy link
Contributor

@dzuelke dzuelke commented Jan 30, 2024

GUS-W-14901875
GUS-W-14901894

We need to dump the FPM config for WEB_CONCURRENCY calculation, and so we can re-use a bunch of the logic and make the code a bit neater
Turns out that bug which would not allow overriding of FPM config php_value settings in .user.ini was fixed in... PHP 7.2: https://bugs.php.net/bug.php?id=75212

Also, that behavior where a later declaration does not override a newer one is probably a bug: php/php-src#13249

We now use php-fpm -tt to dump the config, since that will have stuff printed in evaluation order - if the bug above ever gets fixed, we have to do nothing.

This also removes the need for us to handle the PHP-FPM config include directives ourselves, and as a result, variable expansion and globbing now work in these!

GUS-W-14901875
It is now all handled by autotune.php, and available RAM is in human readable format.

The removal of the read command also makes errors from autotune.php bubble up.

GUS-W-14901894
@dzuelke dzuelke requested a review from a team as a code owner January 30, 2024 19:41
@dzuelke
Copy link
Contributor Author

dzuelke commented Jan 31, 2024

For easier review, here is the output of diff -u <(git diff main..3866053e bin/heroku-php-apache2) <(git diff main..3866053e bin/heroku-php-nginx) ("diff of diffs" for the two files), to show that they contain identical changes except some comments and variable names:

--- /dev/fd/11	2024-01-31 09:45:11.557373911 +0100
+++ /dev/fd/13	2024-01-31 09:45:11.557404452 +0100
@@ -1,13 +1,13 @@
-diff --git a/bin/heroku-php-apache2 b/bin/heroku-php-apache2
-index 98b9c5ac..70bd4fde 100755
---- a/bin/heroku-php-apache2
-+++ b/bin/heroku-php-apache2
-@@ -366,13 +366,34 @@ if [[ -n ${httpd_config:-} || ( ${httpd_config:=$(findconfig "$httpd_version" "$
- fi
- httpd_config=$(php_passthrough "$httpd_config")
+diff --git a/bin/heroku-php-nginx b/bin/heroku-php-nginx
+index a9113307..8423fa04 100755
+--- a/bin/heroku-php-nginx
++++ b/bin/heroku-php-nginx
+@@ -366,13 +366,34 @@ nginx_config=$(php_passthrough "$nginx_config")
+ 
+ nginx_main=$(findconfig "$nginx_version" "$bp_dir/conf/nginx/main.conf")
  
 +fpm_pidfile=$(mktemp -t "heroku.php-fpm.pid-$PORT.XXXXXX" -u)
-+httpd_pidfile=$(httpd -t -D DUMP_RUN_CFG 2> /dev/null | sed -n -E 's/PidFile: "(.+)"/\1/p') # get PidFile location
++nginx_pidfile=$(mktemp -t "heroku.nginx.pid-$PORT.XXXXXX" -u)
 +
 +# we need to dump the FPM config to fetch possible values for memory_limit in php_value and php_admin_value pool declarations
 +# parsing this by hand is cumbersome - there might be recursive includes in the config, glob patterns, etc
@@ -21,10 +21,10 @@
 +trap 'trap - EXIT; rm -f "$fpm_config_tmp"' EXIT
 +echo -e "\n[global]\nlog_level = notice" >> "$fpm_config_tmp"
 +
-+# build command string arrays for PHP-FPM and HTTPD
++# build command string arrays for PHP-FPM and Nginx
 +# we're using an array, because we need to correctly preserve quoting, spaces, etc
 +fpm_command=( php-fpm --pid "$fpm_pidfile" --nodaemonize -y "$fpm_config_tmp" ${php_config:+-c "$php_config"} )
-+httpd_command=( httpd -D NO_DETACH -c "Include $httpd_config" )
++nginx_command=( nginx -c "$nginx_main" -g "pid $nginx_pidfile; include $nginx_config;" )
 +
  mlib="/sys/fs/cgroup/memory/memory.limit_in_bytes"
  if [[ -f "$mlib" ]]; then
@@ -76,7 +76,7 @@
  fi
  
 -fpm_conftest=
--httpd_conftest=
+-nginx_conftest=
 -fpm_config_tmp=$fpm_config
 -case $conftest in
 -	[24])
@@ -88,58 +88,58 @@
 -		;;& # resume
 -	1)
 -		fpm_conftest="-t"
--		httpd_conftest="-t"
+-		nginx_conftest="-t"
 -		;;
 -	2)
 -		fpm_conftest="-tt"
--		httpd_conftest="-t"
+-		nginx_conftest="-t"
 -		;;
 -	3)
 -		fpm_conftest="-t"
--		httpd_conftest="-S"
+-		nginx_conftest="-T"
 -		;;
 -	4)
 -		fpm_conftest="-tt"
--		httpd_conftest="-S"
+-		nginx_conftest="-T"
 -		;;
 -esac
 -
 -fpm_pidfile=$(mktemp -t "heroku.php-fpm.pid-$PORT.XXXXXX" -u)
--httpd_pidfile=$(httpd -t -D DUMP_RUN_CFG 2> /dev/null | sed -n -E 's/PidFile: "(.+)"/\1/p') # get PidFile location
+-nginx_pidfile=$(mktemp -t "heroku.nginx.pid-$PORT.XXXXXX" -u)
 -
--# build command string arrays for PHP-FPM and HTTPD
+-# build command string arrays for PHP-FPM and Nginx
 -# we're using an array, because we need to correctly preserve quoting, spaces, etc
 -fpm_command=( php-fpm ${fpm_conftest} --pid "$fpm_pidfile" --nodaemonize -y "$fpm_config_tmp" ${php_config:+-c "$php_config"} )
--httpd_command=( httpd ${httpd_conftest} -D NO_DETACH -c "Include $httpd_config" )
+-nginx_command=( nginx ${nginx_conftest} -c "$nginx_main" -g "pid $nginx_pidfile; include $nginx_config;" )
 -
  if [[ $conftest ]]; then
 -	echo -e "\n$(basename "$0"): Config testing php-fpm using ${fpm_command[@]}:" >&2
 -	"${fpm_command[@]}"
--	echo -e "\n$(basename "$0"): Config testing httpd using ${httpd_command[@]}:" >&2
--	"${httpd_command[@]}"
+-	echo -e "\n$(basename "$0"): Config testing nginx using ${nginx_command[@]}:" >&2
+-	"${nginx_command[@]}"
 +	case $conftest in
 +		1)
 +			fpm_conftest="-t"
-+			httpd_conftest="-t"
++			nginx_conftest="-t"
 +			;;
 +		2)
 +			fpm_conftest="-tt"
-+			httpd_conftest="-t"
++			nginx_conftest="-t"
 +			;;
 +		3)
 +			fpm_conftest="-t"
-+			httpd_conftest="-S"
++			nginx_conftest="-T"
 +			;;
 +		*)
 +			fpm_conftest="-tt"
-+			httpd_conftest="-S"
++			nginx_conftest="-T"
 +			;;
 +	esac
 +
 +	echo -e "\n$(basename "$0"): Config testing php-fpm using ${fpm_command[@]} ${fpm_conftest}:" >&2
 +	"${fpm_command[@]}" ${fpm_conftest}
-+	echo -e "\n$(basename "$0"): Config testing httpd using ${httpd_command[@]} ${httpd_conftest}:" >&2
-+	"${httpd_command[@]}" ${httpd_conftest}
++	echo -e "\n$(basename "$0"): Config testing nginx using ${nginx_command[@]} ${nginx_conftest}:" >&2
++	"${nginx_command[@]}" ${nginx_conftest}
  	echo -e "\n$(basename "$0"): All configs okay." >&2
  	exit 0
  fi

@dzuelke
Copy link
Contributor Author

dzuelke commented Jan 31, 2024

For reference, outputs now:

Regular:

Using PHP-FPM configuration include 'fpm_custom.conf'
Available RAM is 512M Bytes
PHP memory_limit is 24M Bytes
Starting php-fpm with 21 workers...
Starting httpd...

Verbose:

Using PHP-FPM configuration include 'fpm_custom.conf'
Using PHP-FPM configuration file 'vendor/heroku/heroku-buildpack-php/conf/php/8/php-fpm.conf'
Using PHP configuration (php.ini) file '.heroku/php/etc/php/php.ini'
Using Apache2 VirtualHost-level configuration include 'vendor/heroku/heroku-buildpack-php/conf/apache2/default_include.conf'
Using Apache2 configuration file 'vendor/heroku/heroku-buildpack-php/conf/apache2/heroku.conf'
Reading available RAM from '/sys/fs/cgroup/memory/memory.limit_in_bytes'
Calculating WEB_CONCURRENCY...
Available RAM is 512M Bytes
memory_limit changed by /app/.user.ini
memory_limit overridden by php_admin_value in PHP-FPM configuration
PHP memory_limit is 24M Bytes
WEB_CONCURRENCY=21 (RAM / memory_limit)
Starting log redirection...
Starting php-fpm with 21 workers...
Waiting for php-fpm to finish initializing...
Starting httpd...
Application ready for connections on port 40162.

@dzuelke dzuelke merged commit 679b8be into main Jan 31, 2024
4 checks passed
@dzuelke dzuelke deleted the autotune-fixes branch January 31, 2024 13:06
@heroku-linguist heroku-linguist bot mentioned this pull request Feb 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants