Optimize Your IBM i Web Application Using FastCGI

(Co-written with Alan Seiden)

FastCGIFastCGI 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.SRVPGMcalled 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: Server (followed by parameters)

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:  CommandLine="/QOpenSys/pkgs/bin/php-cgi"

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: StartProcesses="1"

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: ConnectionTimeout="30"

RequestTimeout How long the FastCGI server should wait before responding with an HTTP 408 timeout.

Example: RequestTimeout="60"

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: IpcDir /www/seidenphp/logs

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: IpcPublic *RWX

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"
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=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.
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

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.



0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.