Configuring FastCGI Extension for IIS 6.0

Author: Ruslan Yakushev

Published on December 05, 2007 by iisteam

Updated on December 05, 2007 by iisteam

Average Rating  Rate It (0)

RSS

Introduction

From its first version, IIS has supported CGI ("Common Gateway Interface"). CGI, in its basic form, is a standards-based protocol that allows information servers, such as IIS, to interface with external applications. FastCGI was introduced to the market to address scalability shortcomings of CGI.

This article describes the shortcomings of earlier versions of CGI and defines the need for FastCGI extension for Internet Information Services 6.0. In addition, this article describes configurations settings of FastCGI extension.

CGI, ISAPI and FastCGI on IIS 6.0

CGI

As stated in the introduction, CGI is a protocol that allows information servers to interface with external applications. Because HTTP is stateless, it makes sense that any requests made over HTTP create a new instance of the external application in a new operating system process.

Within the new process, the stdin handle is remapped so that it receives request data from the client, the stdout handle is remapped so that it writes response data to the client, and the command line and operating system environment variables are set to provide other server and request information to the CGI process. 

The disadvantage with CGI on IIS is the relatively expensive process creation on Windows operating systems. Every HTTP request creates a new process, performs the work inside the CGI application, and shuts down the process. On operating systems with very light weight process creation, the performance is bound by the work done inside the CGI application. On operating systems, such as Windows where process creating is expensive, the performance of the CGI application is bound by spinning up the new process. This is why CGI has performed very well on a Unix-based platform, but has not been recommended for IIS.

ISAPI

Despite the disadvantage of CGI on Windows, IIS is capable of keeping up with, and often surpassing, the performance of other web servers. The reason for this is ISAPI ("Internet Server Application Programming Interface"). Unlike CGI, ISAPI is completely internal to the web server process. When a new request is made for an ISAPI application, a new process is not created. Instead, the web server calls an entry point in a DLL that is loaded into the web server process. If the ISAPI application is written with an understanding of how the operating system threading model works, the performance is extremely fast.

For many years, PHP has run on IIS, both through ISAPI and CGI implementations. However, both implementations have disadvantages when running on IIS. As with all CGI applications, the CGI implementation of PHP has a disadvantage due to the performance characteristics of process creation on Windows. The ISAPI implementation has a disadvantage due to threading issues.

When PHP runs as an ISAPI, it runs inside the web server process in a highly multi-threaded environment. While the PHP implementation is thread-safe, many popular extensions to PHP are not thread-safe. If you use a non-thread-safe extension to PHP with ISAPI, the server could become unstable. Hence, many applications cannot run in the ISAPI PHP implementations while others run very well in this environment.

FastCGI

FastCGI offers a compromise solution that delivers both performance and stability. FastCGI allows the host CGI process to remain alive after one request finishes so that the process may be reused for another request. Since the process can be reused many times over, the cost of process creation on Windows drops out of the equation.

The technical difference between normal CGI and FastCGI is that FastCGI has a layer in the process that maps the FastCGI protocol into the stdin, stdout and other resources that CGI uses. Many third-party libraries can be linked into existing CGI source code with very minor modifications to make them work with FastCGI.

FastCGI on IIS runs on top of ISAPI and breaks into the following parts: Applications, the Application Manager and FastCGI protocol support code.

Because web servers handle multiple, concurrent requests, it is necessary to have a pool of processes available and ready to handle incoming requests. In the FastCGI handler, this pool of processes is called an application (to avoid confusion with IIS applications, this article uses the term "process pool"). There are a number of properties of a process pool that you may want to manage. For example, you probably want to specify the number of processes in the pool, or the number of requests a process is allowed to accept before it is shut down and recycled.

The FastCGI handler supports multiple process pools. This is so because you may want to run more than one kind of FastCGI on one server. For example, you wish to configure your server to support both PHP and Ruby. You also have multiple sites on your server, and you do not want requests for those sites to share the same processes. This is particularly true if you want the site processes to run as different users or are concerned that one site might cause a process to become unstable. The part of the server that handles multiple process pools is called the application manager.


Configuring FastCGI

Script Maps

To route requests to the FastCGI handler, you must associate the FastCGI handler with IIS. In IIS 6.0, this is done with an IIS configuration setting called a "script map." Script maps associate file extensions with the ISAPI handler that executes when that file type is requested. In addition, the script map has an optional setting that verifies that the physical file associated with the request exists before allowing the request to be processed. For security reasons, this is the default setting.

However, there are times when you want to allow a request to be processed that is not associated with a physical file. The ISAPI extension that contains the FastCGI handler is called fcgiext.dll. To configure the FastCGI handler to accept PHP requests, create a new script map that associates the ".php" extension with fcgiext.dll. For Ruby, map the ".rb" extension to fcgiext.dll and so on. In IIS 6.0 it is also possible to use a wild card in the script map. In this situation, all requests are routed to a single ISAPI extension. If you create a wild card script map for fcgiext.dll, all requests go to FastCGI, regardless of the file extension requested.

To create a script map for FastCGI handler on IIS 6.0 follow these steps:

  1. Launch inetmgr.exe.
  2. Double click the machine icon for the local computer.
  3. Right click on "Web Sites" and pick "Properties."
  4. Click the tab labeled "Home Directory."
  5. Click the "Configuration…" button.
  6. Click the "Add…" button.
  7. Browse to %WINDIR%\system32\inetsrv\ to select fcgiext.dll as the Executable.

Note: If you are setting this up on 64bit platform in WOW mode, then you must use fcgiext.dll located in %WINDIR%\SysWOW64\inetsrv

    8.  Enter .php as the Extension 
    9.  Enter Verbs as GET,HEAD,POST 
    10  Ensure that "Script Engine" and "Verify that file exists" are checked.

    11.  Click OK

FCGIEXT.ini

Once you have created a script map, you must configure the FastCGI extension settings. Use the fcgiext.ini file found in %windir%\system32\inetsrv\. This file contains various configuration sections and settings that change the behavior of the FastCGI handler.

Regardless of the FastCGI application type that you want to run, you must include a "Types" section in your configuration file. The purpose of the types section is to associate a file extension with a specific process pool and process. So, if you configure IIS script maps to point both .php and .rb files to the FastCGI handler, you must configure the "Types" section to tell FastCGI how these extensions are different from one another. Below, you find a sample configuration file that maps:

[Types]

php=c:\php\php-cgi.exe

php:123154536=PHP Site 1

php:123154537=PHP Site 2

*=Wildcard Mapping

The first line of this file shows that the PHP file extensions are associated with c:\php\php-cgi.exe, which is the PHP CGI application handler. The second and third lines of this sample use site instance identifiers to limit what sites have access to the PHP handler.

You can create configuration on a process-name basis, a file extension (which is optionally site-specific) and a section name. The section name supports declaring arguments for the process. Since different pools running in the same process may require different arguments, we cannot depend on the process name alone to define all of the settings for a given process pool. However, to maintain compatibility with previous technical preview releases of the FastCGI handler, the path of the executable is used to create the starting configuration as in the following sample:

[c:\php\php-cgi.exe]

QueueLength=999

MaxInstances=20

InstanceMaxRequests=500

Since this section does not contain an ExePath setting, the FastCGI handler uses the section name for the path to the executable. The section below is for PHP Site 1, which only applies to the site with 123154536 as its ID:

[PHP Site 1]

ExePath=c:\php\php-cgi.exe

Arguments=site1

QueueLength=1001

MaxInstances=20

IdleTimeout=200

ActivityTimeout=20

RequestTimeout=60

InstanceMaxRequests=1000

In this section, you see that we associate ".php" requests on that site with c:\php\php-cgi.exe. Also, you see that we pass "site1" as an argument to the process when we start it.  This is different from PHP Site 2, which looks like:

[PHP Site 2]

ExePath=c:\php\php-cgi.exe

Arguments=site2

QueueLength=1001

MaxInstances=20

IdleTimeout=400

ActivityTimeout=40

RequestTimeout=120

InstanceMaxRequests=1000

In this case, we pass "site2" as the argument when we start c:\php\php-cgi.exe. 

Note: The "Arguments" setting is optional, and you can pass multiple arguments using a space delimiter. 

If you need a space within a single argument, use quotes around the entire argument, just like the command line.

Note: Every time you change the FastCGI extension configuration in fcgiext.ini file, you must restart the application pools associated with web sites that use FastCGI extension in order for configuration changes to take effect.

Application Pool Settings

FastCGI extension has a set of configuration settings that controls application pool behavior. This section lists all the settings supported by FastCGI and their format:

  • ExePath - The physical path to the process executable to use in the pool
  • Arguments - Arguments to pass to each process in the pool at start time. This setting is optional.
  • EnvironmentVars – Environment variables that are set for the process executable associated with this pool. This setting uses the following format:

EnvironmentVars=Name:Value,Name:Value,…,Name:Value

Example:

EnvironmentVars=VARIABLE1:10000,VARIABLE2:20000

If the environment variable value contains a space character, then enclose the value in quotes. If the environment variable value contains a comma character, then this character is escaped with "/". Similarly, if environment variable value contains "/" then it should be escaped as well.

Example:

EnvironmentVars=VARIABLE1:"C://PHP",VARIABLE2="1/,2/,3"
  • Protocol – This setting specifies the protocol to be used to communicate with the FastCGI process. The allowed values are 'NamedPipe' and 'Tcp'. If not specified, the default value is 'NamedPipe'.
  • QueueLength – This setting specifies the maximum number of requests to this application's process pool that are queued before the FastCGI handler starts returning errors to clients, indicating that the application is too busy. If not specified, the default value is 1000.
  • MaxInstances – This is the highest number of process instances allowed in the process pool. The default is 10. Note that the FastCGI handler will not create this number of processes unless they are needed. If your application never receives more than two concurrent requests, your application only creates two processes.
  • InstanceMaxRequests – This is the number of requests that we send to a process in the pool before it is shut down and recycled. The default value is 1000.
  • IdleTimeout – This is the number of seconds that a process can remain idle without working on a request before it shuts down. The default is 300 seconds.
  • ActivityTimeout – This is the number of seconds that the FastCGI handler waits for I/O activity from a process before it is terminated. The default is 30 seconds.
  • RequestTimeout – This is the maximum amount of time that a FastCGI process is allowed to handle a request before it is terminated. The default is 90 seconds.
  • ResponseBufferLimit – Data from FastCGI processes is buffered before being returned to the client as responses. This property specifies the amount of response data, in bytes, that is buffered for requests to this application. This buffer is flushed to the client once it is full, or when the response is complete, whichever occurs first. If not specified, the default value is 4194304 (4MB).
  • FlushNamedPipe – There are some cases where a FastCGI application might not read all of the data from the named pipe that communicates with the web server. If this happens, the web server waits for a read that is not coming, causing a deadlock on that member of the process pool. This most often happens in the case where the FastCGI process abnormally exits. For instance, the process may have an internal notion of the max number of requests it can handle that is lower than InstanceMaxRequests setting. Setting FlushNamedPipe to 1 causes FastCGI to flush data that might lead to this condition. The default is 0.
  • UnhealthyOnQueueFull – If 1, the worker process hosting is flagged to IIS as unhealthy any time that the application's request queue is filled. IIS checks health whenever it does a ping to the worker process. If that worker process has been flagged as unhealthy, it (along with everything it is hosting) will be recycled. If not specified, the default value is 0.

Wild Card Mapping

The '*' association is used for wild card mapping. This applies only to IIS 6.0, which allows a special kind of script map that applies to all requests. If you configure fcgiext.dll as a wild card handler, this association catches any requests that do not have a more specific configuration associated with the request. For example, the Types section above does not have a ".py" extension configured. If you request a file named "foo.py" using the sample section above, the '*' association is used and the request is routed to the process pool called "Wildcard Mapping".

Look at this section:

[Wildcard Mapping]

ExePath=c:\echo\echo.exe

QueueLength=1000

MaxInstances=20

InstanceMaxRequests=100

IgnoreExistingFiles=1

;IgnoreExistingDirectories=1

Most of this example looks just like the other process pool sections, but it has two additional settings that are only used for wild card script maps (and therefore, only useful in IIS 6.0.). Those settings are IgnoreExistingFiles and IgnoreDirectories.

Imagine the scenario where you have configured the IIS script map that does not verify that a physical file exists before executing the handler. In this scenario, it is convenient to have the FastCGI handler handle requests that are not associated with physical files, but still get IIS to handle other files in the directory normally. That scenario provides the purpose behind these two settings.

  • IgnoreExistingFiles – When set to 1, the FastCGI handler checks if the requested URL is associated with a physical file. If the request is associated with a physical file, the FastCGI handler defers processing the request so that it will be processed external to the FastCGI handler. The default value is 0.
  • IgnoreExistingDirectories – When set to 1, the FastCGI handler checks if the requested URL is associated with a physical directory. If the request is associated with a physical directory, the FastCGI handler defers processing the request so that it is processed external to the FastCGI handler. This setting is useful for allowing default documents and directory listings to be served. The default value is 0.

Site-specific Wild Card Mappings

It is also possible to set a site-specific wild card mapping using the same site ID syntax that file extensions use (i.e.,. "*:12345678=Section Name"). Note, however, that the search order for file extensions is significant. When a request reaches the FastCGI handler, the associations in the types section are checked in the following order:

  1. A specific file extension association specific to the site ID
  2. A '*' association specific to the site ID
  3. A specific file extension association with no side ID specified
  4. A '*' association with no site ID specified

Using FastCGI Configuration Script

To simplify and automate the configuration steps described in previous sections, the configuration script (fcgiconfig.js) is provided with the installation of FastCGI extension. The script is found in %WINDIR%\system32\inetsrv. This script adds and removes script maps and to modifies application pool settings in fcgiext.ini file.

Add New FastCGI Mapping

To add new FastCGI mapping run fcgiconfig.js with the –add switch. When using this switch, you must provide the following parameters:

  • -section:<Section name>. This parameter specifies the name of the section that will be added to the fcgiext.ini file in [Types] block.
  • -extension:<file extension>. This parameter specifies what file extensions are associated with this section.
  • -path:<file path to CGI executable>. Absolute file path to the CGI executable that processes requests for files with extension specified in –extension parameter.
  • -site:<site id>. Optional parameter that specifies to which site the section should be added. If not specified, then the section is added to all sites on your web server.
  • -norecycle. By default, configuration script recycles all applications pools on IIS 6.0 in order for configuration changes to take effect. This optional parameter prevents this recycling.

Examples:


>cscript fcgiconfig.js -add -section:"PHP" -extension:php -path:"C:\PHP\php-cgi.exe"

The above example adds script map for .php extension and updates the fcgiext.ini file.

As an option, you can specify to which site the script map is applied:


>cscript fcgiconfig.js -add -section:"PHP" -extension:php -path:"C:\PHP\php-cgi.exe" –site:1

This example adds script map to "Default Web Site" only.

Remove Existing FastCGI Mapping

To remove existing FastCGI mapping, run fcgiconfig.js with –remove switch. When using this switch, you must provide the following parameters:

  • -section:<Section name>. This parameter specifies the name of the section that is removed to the fcgiext.ini file in [Types] block.
  • -norecycle. By default, configuration script recycles all applications pools on IIS 6.0 in order for configuration changes to take effect. This optional parameter can be used to prevent this recycling.

This example removes the FastCGI mapping for PHP applications


>cscript fcgiconfig.js -remove -section:"PHP"

Configuring Existing FastCGI Mapping

You can use the configuration script to all the FastCGI configuration properties that were described earlier in this article. To set the configuration properties use the –set switch. When using this switch you must provide the following parameters:

  • -section:<Section name>. This parameter specifies the section to which the configuration change is applied.
  • -<Parameter Name>:<Parameter Value>. The name of the parameter to change and its new value. The complete list of possible parameters is found in the section "Application Pool Settings"
  • -norecycle. Use this parameter if you do not want configuration script to recycle application pools after applying configuration change.

This example sets the FastCGI process pool configuration property InstanceMaxRequests for "PHP" section:


>cscript fcgiconfig.js -set -section:"PHP" –InstanceMaxRequests:10000
 

 

Comments

You must Log In to comment.

Page view counter