Ziirish's Home :: Blog

Ziirish's Pub

 
 

Je sais pas si vous avez remarqué dans le footer le "Powered by nginx", mais je vais vous parler de cette petite merveille de technologie. En plus, ça fait un moment que j'ai pas posté d'article en rapport avec l'administration qui est pourtant ma "spécialité".

Nginx est un serveur web au même titre que le célèbre Apache. Comparé à ce dernier, Nginx est un projet récent apparu en 2004. Apache est arrivé en 1995. Mais il a pris note des point faibles de ce dernier pour se faire une place auprès des grands noms (IIS..., Apache, et lighthttpd). Là où Apache tourne avec plusieurs instances (processus), nginx utilise l'approche multithreadée. En résulte une emprunte mémoire réduite. Mais il intègre également des fonctionnalités de reverse-proxy, ce qui permet d'améliorer les performances globales du serveur en métant en cache les contenus statics. ll sert également de load balancer. Mais il ne fait "rien d'autre". Là où Apache, de part son age intègre des dizaines que dis-je des centaines de modules (dont un reverse-proxy également), nginx s'arrête "là" (il existe aussi des modules, mais l'objectif est de rester léger, de faire peu de choses, mais de les faire bien).

Et moi les KISS, j'aime bien (Keep It Simple Stupid). En plus, le fichier de conf est <3 avec une syntaxe "de programmation", un truc logique quoi. Pas comme le pseudo-xml tout moche d'Apache. Je sais pas vous, mais moi quand je dois configurer un Apache, j'attrape des boutons. D'autant plus quand je dois faire ça sur un serveur d'application Oracle sur une machine Windows... Mais faut bien gagner sa vie, et c'est pas avec mon année d'expérience que je vais m'auto-proclamer expert Architecte Systèmes et Réseaux.

Un exemple vaut 1000 mots :


ziirish@labo:~$ ps aux | grep apache
ziirish    383  0.0  0.5   3604   676 pts/0    D+   12:19   0:00 grep --color=auto apache
root       585  0.0  5.8  20660  7312 ?        Ss   Jul09   0:00 /usr/sbin/apache2 -k start
www-data 27633  0.0  9.0  25300 11264 ?        S    06:25   0:06 /usr/sbin/apache2 -k start
www-data 27634  0.0  6.6  22068  8272 ?        S    06:25   0:08 /usr/sbin/apache2 -k start
www-data 27635  0.1  9.5  25952 11912 ?        S    06:25   0:25 /usr/sbin/apache2 -k start
www-data 27636  0.0  7.0  22624  8816 ?        S    06:25   0:08 /usr/sbin/apache2 -k start
www-data 27637  0.0  7.1  23056  8940 ?        S    06:25   0:04 /usr/sbin/apache2 -k start
www-data 27707  0.0  7.3  23148  9108 ?        S    06:25   0:05 /usr/sbin/apache2 -k start


ziirish@fmg:~$ ps aux | grep nginx
root       690  0.0  0.4  34564  1228 ?        Ss   Jul09   0:00 nginx: master process /usr/sbin/nginx
www-data   692  0.0  1.1  35288  2836 ?        S    Jul09   0:02 nginx: worker process

La conf nginx:

worker_processes  1;  

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on; 
}

http {
    include       /etc/nginx/mime.types;

    access_log  /var/log/nginx/access.log;

    sendfile        on; 
    #tcp_nopush     on; 

    #keepalive_timeout  0;  
    keepalive_timeout  65; 
    tcp_nodelay        on; 

    gzip  on; 
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

celle d'Apache :

#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
LockFile ${APACHE_LOCK_DIR}/accept.lock

#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}

#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 15

##
## Server-Pool Size Regulation (MPM specific)
## 

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a
#              graceful restart. ThreadLimit can only be changed by stopping
#              and starting Apache.
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

# event MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_event_module>
    StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

#
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives.  See also the AllowOverride
# directive.
#

AccessFileName .htaccess

#
# The following lines prevent .htaccess and .htpasswd files from being 
# viewed by Web clients. 
#
<Files ~ "^.ht">
    Order allow,deny
    Deny from all
    Satisfy all
</Files>

#
# DefaultType is the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value.  If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#
DefaultType text/plain


#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off

# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log
#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn

# Include module configuration:
Include mods-enabled/*.load
Include mods-enabled/*.conf

# Include all the user configurations:
Include httpd.conf

# Include ports listing
Include ports.conf

#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
# If you are behind a reverse proxy, you might want to change %h into %{X-Forwarded-For}i
#
LogFormat "%v:%p %h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.

# Include generic snippets of statements
Include conf.d/

# Include the virtual host configurations:
Include sites-enabled/

Et ça c'est les confs par défaut. Faut quand même reconnaître que la conf nginx est légèrement plus sexy :P

Voyons maintenant une configuration proxy nginx :

server {
    listen 80; 
    server_name sioux.ziirish.info;

    access_log /var/log/nginx/sioux.access.log;

    location / { 
        proxy_pass  http://31.3.3.7:1337;
        proxy_set_header  X-Real-IP  $remote_addr;
    }   

}

Et ça, y'a moyen de le pondre comme ça en 2 minutes, et sans lire le man (ouais, c'est mal de pas lire le man, mais des fois, c'est comme ça qu'on apprend aussi :) ). Alors que pour faire un truc équivalent sur un Apache, j'ai bouffé des dizaines d'exemples de conf et ça m'a bien pris 2h !

Et enfin, un truc <3 que j'ai jamais testé/vu sur Apache :

server {
    listen 80; 
    server_name blog.ziirish.info;

    access_log /var/log/nginx/blog.access.log;

    location / { 
        root /var/www/nginx-blog;
        index index.php;
        if ($http_user_agent ~ MSIE) {
            rewrite  ^(.*)$  /ie.html  break;
        }   
    }
}

Ou comment filtrer le UA au niveau du serveur.

Bon, par contre, comme je vous l'ai dit plus haut, nginx n'intègre pas de modules PHP/CGI, alors on doit gérer ça à la mano. Et c'est pas plus mal. Alors pour le PHP, on install php-cgi

Ensuite on ajoute à notre conf un proxy-cgi, et c'est gagné !

    location ~ .php$ {
                root /var/www;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME /var/www/nginx-blog/$fastcgi_script_name;
        }