Optimize Your IBM i Web Application Using FastCGI
(Co-written with Alan Seiden)
FastCGI speeds up web applications by pre-starting and managing jobs for popular languages such as PHP. FastCGI can be configured to handle any language that supports the FastCGI interface, as shown in this FastCGI configuration for node.js. When it comes to PHP, you can trust tools such as our CommunityPlus+ PHP siteadd to set good FastCGI defaults. You can also customize fastcgi.conf to accommodate higher traffic, multiple environments, and to solve problems. Read on as we explain how FastCGI works and how to configure it.
History of FastCGI and the “Zend Enabler”
From CGI to FastCGI: Early web servers used the standard Common Gateway Interface (CGI). Every request for a page would spawn a new process to handle the request. This model was simple but slow. Therefore, to improve upon traditional CGI, alternative implementations arose. For RPG and other ILE languages, IBM provided Persistent CGI, which allows programs to stay active between requests. For popular scripting languages such as PHP, FastCGI pre-starts the jobs and keeps them running.
A module to connect Apache and PASE: IBM i’s ILE-based Apache web server connects to PHP and other PASE-based FastCGI servers using an Apache module in QZFAST.SRVPGM
called the Zend Enabler. Despite its name, the Zend Enabler is a generic FastCGI implementation provided by IBM that can connect to any PASE FastCGI server. It looks like this when loaded in Apache:
LoadModule zend_enabler_module /QSYS.LIB/QHTTPSVR.LIB/QZFAST.SRVPGM
FastCGI configuration: Typically, you will find FastCGI configurations in files called /www/webserver/conf/fastcgi.conf
, where webserver is your Apache instance name. After you edit this file, restart your web server instance to make the changes take effect.
Dramatis Personae
Server variables processed by the FastCGI Enabler
Server |
This keyword specifies a server that that can handle FastCGI requests. The Server variable contains many parameters to control each server.
Usage: |
type |
This indicates what kind of server, using an ID such as application/x-httpd-php .The type corresponds to the directives in httpd.conf such as AddType application/x-httpd-php .php and AddHandler fastcgi-script .php .Example: type="application/x-httpd-php" |
CommandLine |
The path to the FastCGI binary; in our case, it’s /QOpenSys/pkgs/bin/php-cgi, which can be used as either a normal CGI executable, or as a FastCGI server.
Example: |
StartProcesses |
Number of parent processes to start. For each parent process, FastCGI will start the number of child jobs specified by PHP_FCGI_CHILDREN. (Total child jobs = StartProcesses * PHP_FCGI_CHILDREN.) Default is 1. We haven’t found any benefit to changing this value.
Example: |
SetEnv |
Each time SetEnv is used, it sets an environment variable for the FastCGI server. Because variables can be specific to the specific FastCGI server, the ones for PHP will be documented later in this article. You can also apply any environment variable understood by PASE software, so setting locales or the PATH is possible via this method.
For examples, see “Variables interpreted by PHP,” below. |
ConnectionTimeout |
How long to wait for a connection to be made. Exact behavior is not well documented, but if a connection timeout occurs, it’s likely that there weren’t enough free PHP jobs.
Example: |
RequestTimeout |
How long the FastCGI server should wait before responding with an HTTP 408 timeout.
Example: |
Other variables processed by the FastCGI Enabler
IpcDir |
Location of socket files enabling the web server to communicate with the FastCGI server. Usually the logs directory.
Example: |
IpcPublic |
Permits all user profiles to alter the socket (referenced above). Not usually recommended. You should only need to do this if your web server switches profiles from the default (such as with Basic Authentication). Considered poor for security because more users can write to the socket. You may, however, need to add this variable if you get an error message like “[zend_enabler:error] Can not connect() to /QOpenSys/pkgs/bin/php-cgi (0.0) – [3401] Permission denied. ”
Example: |
Variables interpreted by PHP
As previously mentioned, SetEnv
options can specify environment variables. The variables below are handled by PHP’s own FastCGI handler:
PHP_FCGI_CHILDREN |
How many PHP worker jobs the PHP FastCGI server should start. This is separate from the Apache number of parallel threads and can be different. The server will start the number of child processes specified here, plus one to coordinate them all. Note that if your web server configuration specifies multiple Listen statements, FastCGI may start an additional set of PHP jobs for each Listen statement. Example: SetEnv="PHP_FCGI_CHILDREN=10" |
PHP_FCGI_MAX_ |
How many requests a PHP job should process before ending and restarting itself. When set to 0, each job will handle an unlimited number of requests. Using a value greater than zero can clean up issues that accumulate over time, such as memory leaks in extensions. Example: SetEnv="PHP_FCGI_MAX_REQUESTS=0" Example: SetEnv="PHP_FCGI_MAX_REQUESTS=100" |
PHPRC |
Optional. When PHPRC is present, PHP will look for php.ini in the directory it specifies, overriding PHP’s built-in setting. Useful for pointing to custom configurations that can be set per web server instance, such as those created by our siteadd tool. Example: SetEnv="PHPRC=/QOpenSys/etc/php" Example: SetEnv="PHPRC=/www/seidenphp/phpconf" |
PHP_INI_SCAN_DIR |
Optional. Similar to PHPRC , but PHP_INI_SCAN_DIR provides a directory name for additional .ini files to scan, typically for extensions. For details on PHPRC and PHP_INI_SCAN_DIR, see the php.net page about PHP configuration files.Example: SetEnv="PHP_INI_SCAN_DIR=/QOpenSys/etc/php/conf.d" Example: SetEnv="PHP_INI_SCAN_DIR= /www/seidenphp/phpconf/conf.d" |
LC_ALL |
An environmental setting for PASE. LC_ALL sets your PASE for i locale. For options, see https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/pase_locales.htm Example: SetEnv="LC_ALL=EN_US" |
Environment variables that may safely be removed with CommunityPlus+ PHP
These variables were set by past versions of Zend Server. Check with your PHP vendor if you believe some may be necessary. Not needed with CP+ PHP.
LDR_CNTRL |
No longer needed with 64-bit PHP. This controls the AIX loader settings; 32-bit Zend Server used this to allocate more memory in the address space for 32-bit PHP. |
LIBPATH |
This controls the AIX loader’s search paths for “library” modules, such as open source dependencies provided by IBM. LIBPATH is not required with CommunityPlus+ PHP, since CP+ compiles the proper library search path into the binaries, but otherwise check with your vendor. It could be useful for certain advanced chroot configurations. |
ZEND_TMPDIR |
Not used with CP+ PHP, but otherwise, check with your vendor. |
INSTALLATION_UID |
Not used with CP+ PHP, but otherwise, check with your vendor. A unique installation ID for Zend Server. |
TZ |
Time zone. Could be useful under some circumstances, but we tend to set the time zone in php.ini. Note that IANA names for time zones won’t work under PASE. |
An example of fastcgi.conf contents, including several optional parameters
1 2 3 4 5 6 7 8 9 10 |
Server type="application/x-httpd-php" CommandLine="/QOpenSys/pkgs/bin/php-cgi" SetEnv="PHPRC=/QOpenSys/etc/php" SetEnv="PHP_INI_SCAN_DIR=/QOpenSys/etc/php/conf.d" StartProcesses="1" SetEnv="PHP_FCGI_CHILDREN=10" SetEnv="PHP_FCGI_MAX_REQUESTS=0" ConnectionTimeout="30" RequestTimeout="60" SetEnv="LC_ALL=EN_US" SetEnv="CCSID=1208" ; Where to place socket files IpcDir /www/seidenphp/logs ; To open up socket permissions (commented out in this case) ;IpcPublic *RWX |
FastCGI is a key to speed and stability
The flexibility of FastCGI lets us accommodate varying workloads, including high traffic sites, and to configure variables to suit each application’s needs. If you would like to learn more, or to discuss having us review your FastCGI or web server configuration, get in touch.
Leave a Reply
Want to join the discussion?Feel free to contribute!