Guru: Right-Size Your PHP
December 3, 2018 Alan Seiden
In my experience doing performance audits, I often point out that while PHP for IBM i comes perfectly configured for small applications, it must often be tuned to handle large workloads. When applications must accommodate hundreds or thousands of users, or use AJAX technology, two easy changes should be considered for PHP and Apache configurations.
1. PHP_FCGI_CHILDREN Setting In fastcgi.conf
On IBM i, Zend Server installs a configuration file called fastcgi.conf. Among other settings, it includes PHP_FCGI_CHILDREN, which determines how many PHP jobs run when its Apache server is started. The file — /www/zendphp7/conf/fastcgi.conf (Zend Server 9 or higher) or /www/zendsvr6/conf/fastcgi.conf (Zend Server 6, 7, 8, or 8.5) — includes the following setting:
SetEnv="PHP_FCGI_CHILDREN=10"
The above setting specifies that there should be 10 PHP jobs to handle incoming. While this number is acceptable when requests run and finish quickly with moderate workload, it may be too small when some requests run slowly (from slow queries and the like) or to accommodate high numbers of users or AJAX requests (AJAX causes multiple PHP requests per page to run).
How to find the best setting? At Seiden Group, we run special monitoring code to measure workload throughout the day, but you can take a sample by looking at WRKACTJOB and seeing how many PHP jobs (named ZENDPHP7 or ZENDSVR6) have a job status other than TIMW.
Example of an “idle” (waiting for work) PHP job:
ZENDSVR6 QTMHHTTP BCI .0 PGM-php-cgi.bi TIMW
Rogue Wave’s Rod Flohr has written a detailed article about how to increase FastCGI child processes for PHP. In a nutshell, we edit the fastcgi.conf file to increase the number of child processes. I use something like Zend Studio or even WRKLNK to edit the file.
Look for this:
SetEnv="PHP_FCGI_CHILDREN=10"
Set the number to the number of processes you want. For example, to set it to 25, change it to this:
SetEnv="PHP_FCGI_CHILDREN=25"
Be sure that this line in the configuration remains all on one line. Save and exit.
Restart Apache for this change to take effect.
I suggest making modest changes because increasing the processes too abruptly may allow in more workload than you really want to run at one time. Performance issues may indicate other issues to resolve, such as queries that need optimization or to address PHP session locking (a common issue with AJAX), examples of issues that may be addressed in a full performance audit.
2. ThreadsPerChild Setting In Apache Configuration httpd.conf
Apache provides further controls over site traffic. The ThreadsPerChild directive controls the maximum number of simultaneous HTTP connections. Defaulting to 40, ThreadsPerChild’s limit will include not only PHP scripts, but all file requests, including cascading style sheets (CSS), JavaScript, and images.
The httpd.conf file can be edited directly in /www/zendphp7/conf/httpd.conf (or in zendsrv6 for older versions of PHP), or using IBM’s HTTP configuration administration site at port 2001, which requires starting the *ADMIN web instance. You can find more details here.
If you see a value for ThreadsPerChild, such as:
ThreadsPerChild 40
Then you can increase the 40 to something higher.
If you see no value at all then you may add the directive yourself. To set a value of 100, you could add:
ThreadsPerChild 100
How to determine the best ThreadsPerChild value? Look at the “real-time server statistics” area on the HTTP Admin page (from port 2001 as specified earlier) during an active time for your site, and see how many Active Threads and Idle Threads are shown. If you have plenty of Idle Threads then you are doing fine, but if there are zero Idle Threads, or even worse, a number in the billions (indicating a negative number), you’ll want to increase ThreadsPerChild.
For additional information, see this link on the Seiden Group website.
PHP Has Hit The Big Time On IBM i
IBM i shops have gone far beyond “kicking the tires” with PHP. This open source language is at the heart of many mission-critical production applications that have grown over time.
In my experience doing performance audits, I’ve found that the PHP_FCGI_CHILDREN and ThreadsPerChild settings are often either overlooked, or increased too much. Setting the optimal values (like the porridge in the Three Little Bears, not too hot, not too cold, but just right), can make the difference when configuring PHP on IBM i for excellent performance.
An IBM Champion and founder of Seiden Group, Alan Seiden leads a team that mentors clients in building APIs and web/mobile applications using open source, PHP, Python, Node.js, and IBM i business logic. Alan’s passion for the IBM i community inspires him to host the bi-annual CIO Summit and offer a free monthly tips newsletter.