FastCGI

Author:Frank Warmerdam
Contact:warmerdam at pobox.com
Author:Howard Butler
Contact:hobu.inc at gmail.com
Last Updated:

15/07/2008

Introduction

FastCGI est un protocole pour garder les applications web de style cgi-bin lancé sous forme de démon pour optimiser la préservation des caches mémoires, et amortir les coûts important de démarrage (comme les coût de connections à la base de données) pour de nombreuses requêtes.

Obtenir le logiciel nécessaire

  1. Il y a 3 pièces dans le puzzle FastCGI de MapServer. D’abord, vous avez besoin de la bibliothèque FastCGI. Elle peut être téléchargée à partir de http://www.fastcgi.com/. Cette bibliothèque nécessite l’ensemble habituel configure, make, make install. Une complication supplémentaire est qu’il s’installe par défaut dans /usr/local par conséquent vous avez besoin d’ajouter à la commande configure un –prefix=/usr pour le placer au bon endroit qui est déjà visible dans ldconfig.

  2. En assumant que vous avez Apache , la prochaine pièce dont vous avez besoin est le module fastcgi. Il existe deux implémentations de fastcgi pour apache :

    • mod_fcgid: mod_fcgid est la manière la plus récente et recommandée pour lancer des programmes fastcgi pour des versions apache récente. Il peut être téléchargé à partir de la page fcgid d’Apache

    • déprécié mod_fcgi : mod_fcgi dépens de la version d’Apache que vous utilisez, assurez vous donc de télécharger le fork correct (Apache 1.3 vs. Apache 2).

  3. La troisième et dernière étape est de compiler MapServer avec la gestion de FastCGI. C’est assez aisé, et tout ce dont vous avez besoin est de dire à “configure” où est installé la bibliothèque FastCGI. Si vous avez changé la variable prefix comme décrit plus haut, cela devrait être :

./configure [other options] --with-fastcgi=/usr/local

Avec ces deux étapes en place, le CGI de MapServer (mapserv) doit posséder l’activation FastCGI. Vous pouvez vérifier cela en le testant avec la ligne de commande :

[hobu@kenyon mapserver-6.2.0]# ./mapserv -v
MapServer version 6.2.0 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP
SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT
SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=FASTCGI INPUT=EPPL7
INPUT=SDE INPUT=ORACLESPATIAL INPUT=OGR INPUT=GDAL
INPUT=SHAPEFILE DEBUG=MSDEBUG

Configuration de mod_fcgid

  1. Modifier http.conf pour charger le module FastCGI

LoadModule fcgid_module modules/mod_fcgid.so
  1. Ajouter un handler Apache pour les applications FastCGI.

AddHandler fcgid-script fcgi
  1. Définir les informations de traitement FastCGI

<IfModule mod_fcgid.c>
   FcgidMaxProcessesPerClass 30
   FcgidInitialEnv PROJ_LIB /usr/local/share/proj
   FcgidInitialEnv LD_LIBRARY_PATH "/usr/local/lib:/usr/local/pgsql/lib:/usr3/pkg3/oracle9/lib"
</IfModule>

Déprécié Configuration mod_fcgi

Cette section est laissée pour référence. La façon recommandée de lancer le programme fastcgi sous apache est d’utiliser mod_fcgi, comme décrit plus haut.

  1. Modifier http.conf pour charger le module FastCGI

    LoadModule fastcgi_module /usr/lib/apache/1.3/mod_fastcgi.so
    
  2. Ajouter un handler Apache pour les applications FastCGI.

    AddHandler fastcgi-script fcgi
    
  3. Définir les informations de traitement FastCGI

    FastCgiConfig -initial-env PROJ_LIB=/usr/local/share/proj
    -initial-env LD_LIBRARY_PATH=/usr/local/lib:/usr/local/pgsql/lib:/usr3/pkg3/oracle9/lib
    -appConnTimeout 60 -idle-timeout 60 -init-start-delay 1
    -minProcesses 2 -maxClassProcesses 20 -startDelay 5
    

Configuration commune mod_fcgid/mod_fcgi

  1. Installez une copie de l’exécutable mapserv (initialement mapserver ou mapserv.exe) dans le répertoire cgi-bin avec l’extension .fcgi (ie. mapserv.fcgi). Utilisez cet exécutable quand vous souhaitez utiliser fastcgi.

    Pour certaines plate-formes, le lien MapServer devrait être ensuite changé depuis:

    http://your.domain.name/cgi-bin/mapserv?MAP=/path/to/mapfile.map
    

    Par:

    http://your.domain.name/cgi-bin/mapserv.fcgi?MAP=/path/to/mapfile.map
    

    Pour les autres plate-formes, le lien MapServer devrait être ensuite changé depuis :

    http://your.domain.name/cgi-bin/mapserv.exe?MAP=/path/to/mapfile.map
    

    Par:

    http://your.domain.name/cgi-bin/mapserv.fcgi?MAP=/path/to/mapfile.map
    
  2. Dans votre mapfile, définissez une directive PROCESSING pour informer FastCGI de mettre en cache les informations de connections et des couches de toutes les couches pour lesquelles le cache de connections est désiré - ie. toutes les couches lentes.

    PROCESSING "CLOSE_CONNECTION=DEFER"
    

Problèmes communs

Permissions fichier

Fedorac Core 3 n’autorise pas FastCGI d’écrire dans les logs des processus (quand vous utilisez la version d’Apache 2 de Red Hat plutôt que la votre). Cela est décrit ici.

FastCGI a besoin d’écrire ses informations de sockets quelque part. Cela peut être définie avec la directive “FastCgilpcDir”.

FastCGI sur Win32

Utilisateurs MS4W

MS4W (MapServer pour Windows) >= version 2.2.2 contient MapServer compilé avec la gestion de FastCGI. La version de MS4W >= 2.2.8 contient également le module Apache nécessaire (mod_fcgid), et les utilisateurs doivent suivre les instructions du README pour paramétrer FastCGI avec leur application.

Compiler fcgi-2.4.0

J’ai utilisé libfcgi-2.4.0 pour utiliser avec Apache2 depuis le site http://www.fastcgi.com.

Patch binaire IO

Il est critique que stdio soit en mode binaire quand les images PNG et autres formats soit écrit. Pour accomplir cela avec la version de stdio utilisée par la bibliothèque FastCGI, J’ai dû réaliser cette modification dans le fichier libfcgi/fcgi_stdio.c au sein de la distribution fcgi-2.4.0.

Dans FCGI_Accept(), faire les changements suivant

if(isCGI) {
  FCGI_stdin->stdio_stream = stdin;
  FCGI_stdin->fcgx_stream = NULL;
  FCGI_stdout->stdio_stream = stdout;
  FCGI_stdout->fcgx_stream = NULL;
  FCGI_stderr->stdio_stream = stderr;
  FCGI_stderr->fcgx_stream = NULL;

  /* FrankWarmerdam: added so that returning PNG and other binary data
     will still work */
#ifdef _WIN32
  _setmode( _fileno(stdout), _O_BINARY);
  _setmode( _fileno(stdin), _O_BINARY);
#endif

} else {

Ajouter également ce qui suit juste avant la fonction FCGI_Accept()

#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif

Je suis sûr qu’il y a une meilleure façon d’y parvenir. Si vous savez comment, s’il vous plaît faites le moi savoir !

Compiler libfcgi

Le fichier makefile.nt devrait convenir. Assurez vous juste que vous avez lancé VCVARS32.BAT (puisque nécessaire pour compiler MapServer) puis lancez la commande

nmake /f makefile.nt

Puis les fichiers .lib et .dll seront dans libfcgi/Debug?. Assurez vous de copier les DLL quelque part d’approprié (tel que le répertoire cgi-bin).

Autres problèmes

1) FastCGI’s receive a very limited environment on win32, seemingly even more restricted than normal cgi’s started by apache. Make sure that all DLLs required are either in the fastcgi directory or in windowssystem32. Any missing DLLs will result in very cryptic errors in the error_log, including stuff about Overlapping read requests failing or something like that.

2) Make sure you use a libfcgi.dll built against the same runtime library as your mapserv.exe (and possibly libmap_fcgi.dll) or you will suffer a world of pain! Different runtime libraries have different “environ” variables (as well as their own stdio and heaps). You can check that everything is using MSVCRT.DLL (or all using MSVCRTD.DLL) using the MS SDK Dependency Walker.