Erstellung einer FastCGI Anwendung
Ein FastCGI Programm kommuniziert mit dem Server Modul und bekommt Eingaben und Variablen direkt von diesem übergeben. Umgekehrt wird die Ausgabe nicht auf stdout/stderr geschrieben, sondern dem Modul übergeben. Aus diesem Grund wird nicht mehr stdio.h eingebunden, sondern die Headerdatei fcgi_stdio.h aus dem Developement-kit.
Durch den Header wird und unter anderem die Funktion int FCGI_Accept(void) zur Verfügung gestellt, die Anfragen vom Server entgegennimmt und die Umgebung des Webservers für die FastCGI Anwendung zur Verfügung stellt.
Beim ersten Aufruf der Anwendung wird nun die Initialisierung des Programms ausgeführt und die Funktion startet die eigendliche Anwendung. Beim nächsten Aufruf wird nur noch die eigendliche Anwendung gestartet, ohne das Programm neu zu Initialisieren.
Der Rückgabewert der Funktion ist 0 für einen erfolgreichen Aufruf und -1 für einen Fehler.
Wir benutzen Die Funktion int FCGI_Accept(void) also in einer Schleife, in der die Anfragen des Servers verarbeitet werden. Alles was vor dieser Schleife steht, wird nur beim ersten Aufruf der Anwendung ausgeführt, wodurch wir in der Lage sind Operationen, die bei jedem Aufruf gleich bleiben hier auszuführen.
int main(void)
{
unsigned int counter = 1;
while(FCGI_Accept() >= 0)
{
printf("Content-type: text/html\r\n\r\n");
printf("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n");
printf(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n\r\n");
printf("<html>\r\n");
printf(" <head>\r\n");
printf(" <title>FastCGI ist schnell!</title\r\n");
printf(" </head>\r\n");
printf(" <body>\r\n");
printf(" <h1>Das erste FastCGI</h1>\n\r");
printf(" <p>Das FastCGI wurde bisher %d mal aufgerufen</p>\r\n",
counter++);
printf(" </body>\r\n");
printf("</html>\r\n");
}
return 0;
}
Das Programm wird gegen die Bibliothek libfcgi gelinkt. Die Pfade zu Bibliotheken und Header müssen Sie Ihrem System entsprechend anpassen. Die Option -lfcgi ist dafür zuständig, dass der Conpiler die Bibliothek libfastcgi.a hinzulinkt und bei den meisten Compilern erforderlich.
TTY
you@host > gcc -o index.fcgi index.c -idirafter /usr/local/include -L/usr/local/lib/ -lfcgi
you@host >
Jetzt kann das Programm im Webbrowserr aufgerufen werden. Beim ersten Aufruf werden wir folgendes in der error.log finden:
(dynamic) server "/usr/local/www/fcgi-bin/index.fcgi" started (pid 22642)
Dieser Eintrag wird nur beim ersten Aufruf des Programms geschrieben, das Programm läuft ab jetzt durch. Dies können wir anhand unserer Variablen counter überprüfen, die ja beim Programmaufruf initialisiert wird und dann in der Schleife inkrementiert wird.
Beim ersten Aufruf des Programms sollte also folgendes im Browser zu sehen sein:
Das erste FastCGI
Das FastCGI wurde bisher 1 mal aufgerufen
Wenn jetzt die Seite neu geladen wird, sollte der Counter jedesmal um 1 inkrementiert werden, da die Variable ja nicht durch eine neue Initialisierung wieder auf 1 gesetzt wird.
"Tolle Wurst" werden sie jetzt sagen, "was bringt mir das?"
Dieses Programm sicher nicht viel, da es nur die Funktionsweise demonstrieren soll. Das Programm ist zu klein, als man von FastCGI einen Vorteil haben wird und die Aufrufe werden sich wohl eher in Grenzen halten. Dennoch stellt es die Grundlage zu schnellen Webanwendungen dar.
Wir können einfach mit unsigned int sleep(unsigned int sekunden) eine Arbeit simulieren, die eine Anwendung bei jedem Programmaufruf ausführen muss, um zu zeigen, wie wir Tempo machen können. Ich gehe einfach mal davon aus, dass diese simulierte Arbeit 3 Sekunden dauert und ändere das Programm wie folgt:
int main(void)
{
unsigned int counter = 1;
// Hier kommt unser eingesparter Part
sleep(3);
while(FCGI_Accept() >= 0)
{
printf("Content-type: text/html\r\n\r\n");
printf("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n");
printf(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n\r\n");
printf("<html>\r\n");
printf(" <head>\r\n");
printf(" <title>FastCGI ist schnell!</title\r\n");
printf(" </head>\r\n");
printf(" <body>\r\n");
printf(" <h1>Das erste FastCGI</h1>\n\r");
printf(" <p>Das FastCGI wurde bisher %d mal aufgerufen</p>\r\n",
counter++);
printf(" </body>\r\n");
printf("</html>\r\n");
}
return 0;
}
Nachdem das Programm neu übersetzt ist muss nun das Programm neu gestartet werden, da es ja immer noch läuft und die Änderung daher nicht greifen würde. Man könnte jetzt einfach den Apache neu starten, wir senden aber der Einfachheit halber dem Programm ein SIGTERM. Die PID des Programms entnehme ich dem Eintrag in der error.log:
TTY
# kill -SIGTERM 22642
#
Auf Grund der Aktion wird folgender Eintrag in die error.log geschrieben:
(dynamic) server "/usr/local/www/fcgi-bin/index.fcgi" (pid 22642) terminated by calling exit with status '0
Wenn wir jetzt das Programm erneut im Browser aufrufen, wird der erste Aufruf etwas mehr als 3 Sekunden dauern. Jeder weitere Aufruf wird aber annähernd direkt beantwortet, da unser simulierte Arbeit bereits erledigt ist.
Daraus folgt, dass es sinnvoll ist das Design einer Anwendung anders zu gestalten als bei der bisherigen Arbeitsweise mit CGI. Es ist also sinnvoll Arbeiten, wie das Einlesen von Konfigurationsdateien, Templates, etc. vor der Schleife auszuführen, um so den Server zu entlasten.
Weiter mit Was zu beachten ist
