Some time ago I was assigned to write an online auction engine. I had a choice - to make the engine as a regular CGI, or to make something more interesting. I decided to apply the FastCGI technology in the development of the engine.
FastCGI is a client-server protocol that provides interaction between a web server and an application. FastCGI is a further development of the CGI protocol.
What is the difference?
In the case of a regular CGI application, the interaction between the web server and the application is done through STDIN and STDOUT. In the case when FastCGI is used, the interaction between the client and the server is done via Unix Sockets or via TCP / IP.
')
The more interesting of these two options is TCP / IP communication. This option provides two key benefits:
1) FastCGI applications can be run not only on the same server as the web server, but also on any other. There can be any number of such servers and FastCGI applications running on them, and this, in turn, provides almost unlimited scope for system scaling. Has the system stopped handling loads? Do not worry - you can very simply, completely rebuilding nothing, add the required number of servers. The maximum intervention in the existing system will consist, merely, in adding a line with a list of new IPs to the web server configuration.
2) FastCGI application can be implemented as a daemon, i.e. it can itself be a server. A typical CGI application is launched by the web server with each new request. The launch of the application takes the lion's share of the time, often the launch takes more time than the useful work performed by it. A FastCGI application is always running, it does not need to waste time on launch, it only needs to perform useful work.
For these charms you have to pay. First, writing a FastCGI application is somewhat more complicated than writing a CGI application. Secondly, the web server requires some additional configuration, and, possibly, replacement.
Let's start with the web server.
In our case, the web server will play an extremely small role; it will neither resolve virtual hosts, nor execute scripts, nor give statics. All his work will be limited to the transfer of the request from the browser to the FastCGI application. For such a task is well suited
nginx .
To configure nginx to work with our application, the following construction must be added to the nginx config:
# Any queries in which the path will start from the fcgi-bin directory,
# will be passed to the FastCGI application for processing.
location / fcgi-bin / {
# Where to send requests
# in this case, the FastCGI application is on the same computer and is listening on port 9000
fastcgi_pass localhost: 9000;
}
(for details on setting up nginx, please refer to the
source )
Run nginx. Suppose a virtual host test.host has been configured in nginx, then the browser request to the address
test.host/fcgi-bin will be transmitted by nginx to our FastCGI application. While the application itself is not yet, something like this will be displayed in the browser:
“The page you are looking for is temporarily unavailable. Please try again later. „
This is normal. It should be so.
We now turn directly to writing a FastCGI application.
The FastCGI protocol is implemented in Perl as an
FCGI module. Please note that there are other modules on CPAN that allow you to work with FastCGI, for example, CGI :: Fast, but all of them are just add-ons over FCGI. We will work directly with the “fundamental” FCGI module.
#! / usr / bin / perl
# To heighten the order
use strict;
use warnings;
# This module implements the FastCGI protocol.
use FCGI;
# Open the socket
# our script will listen to port 9000
# length of the connection queue (backlog) - 5 pieces
my $ socket = FCGI :: OpenSocket (": 9000", 5);
# Getting to listen
my $ request = FCGI :: Request (\ * STDIN, \ * STDOUT, \ * STDERR, \% ENV, $ socket);
my $ count = 1;
# Endless cycle
# for each accepted request, one cycle is performed.
while ($ request-> Accept ()> = 0) {
# Inside the loop, all useful work is performed
print "Content-Type: text / plain \ r \ n \ r \ n";
print $ count ++;
};
Let us examine some points in more detail.
The OpenSocket function opens a socket and binds the port 9000 to it. Do not forget - it was this port that we previously specified in the nginx config. Don't forget yet - ports below 1024 cannot be opened without being root.
The backlog parameter of this function sets the number of connections that will wait in the queue while previous connections are serviced. Honestly, I did not understand how this parameter works. Theoretically, if the queue is full, new connections should be dropped. But my change of this parameter doesn’t have a visible effect, what number do not indicate - all connections are still lining up in the queue, none is reset. Probably, I am missing something somewhere, but this does not seem to affect the performance of the script.
The Request function creates a request handler. The handler intercepts the standard descriptors and binds them to the web server. This means, in particular, that if at the request of the script some error occurs, the message about it will not be displayed on the console, but given to the web server. You need to search for this message in the nginx log. Well, in general, conventional CGI scripts have similar behavior in this regard, with the only difference that the CGI application logs are near, and the FastCGI application logs can be located on a completely different server.
Do not neglect the output of the header "Content-Type" (well, or at least some of the title). Without this, nginx will refuse to display anything to the browser. In general, this behavior is also similar to the behavior of a web server when working with a regular CGI application.
Well, they wrote the script, run it. If you have not made a syntax error anywhere, the script will start silently, will not output anything and will not let go of the console - this is normal, it should be so. Now the script has to listen to port 9000 and wait until it is accessed by the web server.
Now we launch the browser and open the address
test.host/fcgi-bin - remember, you already opened it when you checked the nginx configuration? But this time, instead of the message about the inaccessibility of the page, a simple figure 1 should appear. Press the F5 button. The figure should increase.
Congratulations! You have written and launched the FastCGI application. This application is still very primitive and is not yet a real FastCGI server, but, by and large, you have already become acquainted with FastCGI technology.
In the next part - the demonization of the application, turn the script into the server.
(
original article )