This holiday season, give your site the gift of asynchronous reverse proxy server Nginx.

Merry Nginxmas: A beginner’s guide
Kommentare

Nginx (pronounced “engine x”) is an open source reverse proxy server for http, https, and the smtp, imap and pop3 mail protocols. It is an interesting and increasingly popular alternative to Apache for serving PHP, and this month we will take a look at how it works and how to use it.


©iStockphoto.com/studio9400

Webservers of Xmas Past

The Nginx project started with a strong focus on concurrency at a time when webserver capabilities made serving greater than 10,000 simultaneous requests a matter for multiple hosts. The “C10K problem”, as it is known, was resolved for the Russian search engine Rambler by Igor Sysoev, with the first release of his new, event driven and asynchronous webserver Nginx.

The first public version was released in October 2004, and each version since then has been available under the 2-clause BSD-like license, free to download, modify, use and distribute, from nginx.org Since then its use has grown and grown, especially in the higher performance site sector.

Unlike the industry standard server Apache, Nginx responds to requests asynchronously with an event-based approach. It consumes fewer system resources per request than Apache does with its thread-driven process and hence can manage a higher number of connections within the same operating system and hardware footprint.

Reverse proxy servers, which are functionally equivalent to their forward proxy server namesakes, insulate hosts from networks, rather than clients. Deploying a reverse proxy has its advantages: from the normalization of DNS or protection of your IP addresses, to a variety of caching configurations and the management of separated services. As well as being a reverse proxy server out of the box, Nginx is also a capable load balancer and ideally suited to be first host of response, though it can equally be deployed alone to serve files and handle CGI script requests.

Getting hold of a copy is easy. The official site hosts repositories for Debian/Ubuntu, RHL/Cent, BSD and an official Win32 binary at wiki.nginx.org/Install. If you plan to run PHP scripts you will additionally need the FastCGI Process Manager php-fpm (the Python equivalent is python-flup) since all script execution in Nginx must be over CGI. There is a good package in the Debian repos for php-fpm, so a quick sudo aptitude install php5-fpm should get you on your way. The EPEL and Remi repos have up to date versions for yum installations, a gist of my notes is available at gist.github.com/blgreenaway/6810654.

The Nginx wiki also includes build from source instructions, which you may need for module additions later and Packt Publishing currently ship their second edition of the book, “Nginx HTTP Server” containing many useful Nginx setup tips.

Who uses Nginx?

NetCraft’s July 2013 Web Server survey recorded nginx as the third most widely used web server across all domains with 13 % of all surveyed sites. W3Techs saw 17 % of the top 1 million sites, 26 % of the top 100,000 sites and 34% of the top 10,000 hosted by nginx.

  • WordPress.com – Has used nginx in loadbalancers since 2008, all backend http since 2012 (source)
  • Netflix.com – “We use the nginx web server for its proven scalability and performance” (source)
  • php.net
  • Pinterest.com
  • Sourceforge.com
  • Instagram.com

Webservers of Xmas Present

Each instance of Nginx operates under a configuration file composed of a hierarchical series of logical blocks, identifying behaviours and services by directives and parameters. These configuration files will appear familiar to anyone who has worked with Apache or any other server before now. The configuration file and any other file includes it might declare, are loaded and passed once at each server start, and remain active and unalterable until the next restart or reboot.

In our first example below, we set the http server to listen on port 80, as expected, give it a name – testsite.local – and identify logging files and the root for the filesystem to serve from. Then we add two additional blocks called location which refer to the HTTP request being made.

If Nginx sees the request URL matches a location block, the directives within that block will be followed, within that block Nginx will override any previously declared parameter for a directive if it exists.

http {
    server {
        listen 80;
        server_name testsite.local;
        access_log /var/www/html/testsite.local/logs/access.log;
        error_log /var/www/html/testsite.local/logs/error.log;
        root /var/www/html/testsite.local/public_html;

        location / {
            index index.html index.htm index.php;
        }

        location ~ .php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
                fastcgi_param  SCRIPT_FILENAME/var/www/html/testsite.local/public_html$fastcgi_script_name;
        }
    }
}

Bow image ©Software & Support Media

The syntax for location is location [= | ~|~*|^~|@] pattern { … } and the matching precedence employed by Nginx is as follows: location blocks with the = modifier, location blocks with no modifier at all, location blocks with the ^~ (pattern begins with) modifier, location blocks with the ~ or ~* (pattern or pattern ends with) modifier. If no location block has been found to match the request at this point, a block with no modifier whose string matches the start of the request will be used.

Our example directs all requests the root towards index.html, index.htm or index.php and all requests to a php script towards the service listening at localhost:9000, where php-fpm runs in its default settings. Nginx will match the php script regardless of query string parameters and forward them on.

The file fastcgi_params included by the listing above establishes environment variables specific to the operation of FastCGI and can be tailored to suit your needs. It does not replace php.ini, which will be parsed and loaded when you start your php-fpm service.

http {
    gzip on;
    expires 86400;

    server {
        listen 80;
        server_name testsite.local;
        access_log /var/www/html/testsite.local/logs/access.log;
        error_log /var/www/html/testsite.local/logs/error.log;
        root /var/www/html/testsite.local/public_html;

        location / {
            index index.html index.htm index.php;
        }

        location ~ .php$ {
            expires 3600;
            include /etc/nginx/fastcgi_params;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
                fastcgi_param  SCRIPT_FILENAME/var/www/html/testsite.local/public_html$fastcgi_script_name;
        }

        location /rawserve/ {
            gzip off;
        }

        location /nevercache/ {
            expires -1;
        }   

    }
}

This second example adds two further location blocks and a pair of directives to the http block. Turning on gzip compression for all content returned by Nginx is set by gzip on in the http block. Cache control headers for expiry are managed through the expiry directive, taking parameters in second by default. All files now served by this server will be compressed, with an expiry time of 1 month except for the results of php scripts (which will expire after 1 day) and the contents of the directory nevercache – a negative value sends ‚do not cache‘ headers instead. Also, a request to the directory named rawserve will return non-gzipped content.

location /wp-admin/ {
    index  index.php;
    auth_basic "mysite : secured area";
    auth_basic_user_file /etc/nginx/conf.d/allowedusers_htpasswd;
}

Location blocks can specify behaviours beyond CGI too. In this example, the WordPress admin area is secured by credentials stored in a password file at /etc/nginx/conf.d/allowedusers_htpasswd.

location /not-here-elsewhere/ {
    rewrite ^ http://www.example.com/temporary/resource/location redirect;
}

location /not-here-elsewhere/ {
    rewrite ^ http://www.example.com/permanently/moved/location permanent;
}

If you wish to redirect requests, the rewrite directive can modify the request on your behalf according to the pattern and replacement rules you give it. Both permanent 301 and temporary 303 redirections are shown in this example.

The next listing adds another new block – upstream – and demonstrates Nginx as a reverse proxy for Apache. Here, anything matching the php script pattern is forwarded on to one of the upstream servers, according to the load balancing rules for each.

upstream apache {
    ip_hash;
    server 192.168.0.1:8080;
    server 192.168.0.2:8080;
    server 192.168.0.3:8080 weight=2;
    server 192.168.0.4:8080 backup;    
}

server {
    server_name www.example.com example.com;
    root /var/www/html/example.com/public_html;
    [..]
    location ~ .php$ {
        # Proxy all requests to dynamic php content to Apache
        # proxy_pass  127.0.0.1:8080; use this line for one local Apache instance
        proxy_pass  http://apache:8080;
    }

    location / {
        # All other static content options go here
        expires 30d;
    }
}

With a weight of 2, the third upstream server will receive twice as many requests as each of the others. The last of the list, marked backup, will only receive requests if each of the other three are down. The additional ip_hash; directive should be added to the upstream block to keep the PHP sessions sticky; any static, non PHP script content will be served directly by Nginx. Therefore, no changes need be made to your current Apache hosting environment to take advantage of deploying Nginx up front. By swapping the commented-out proxy_pass line for the active one, a localhost Apache instance rather than a round robin cluster could be proxied instead.

Webservers of Xmas Yet to come

Though Nginx was designed for a very specific purpose and has only a fraction of the number of extensions written for it that Apache does, it is by no means half-baked. Like Apache, Nginx may be extended by adding first- and third-party modules, though unlike Apache these extensions must be compiled in before use.

In the last two years, module additions have included Web- Sockets, SPDY, HTTP streaming support for FLV and MP4. As of OpenBSD release 5.2, Nginx has become the default HTTP server, replacing a fork of Apache 1.3. That counts as real skin in the long term game. More recently, the Nginx Inc company was founded, financed and began offering technical support similar to offerings from Red Hat. Having opened new offices in San Francisco and recommitted to maintaining the project as Open Source, Nginx looks to have a bright and well supported future.

As to Apache, I shan’t attempt to speculate too much. But it would be hard to imagine any dramatic change to its core architecture or the approach which has driven its success. Apache deployment options have always benefited from the range of third-party modules, and that is certain to continue: that territory is far more fully mapped in the Apache space than with Nginx.

When Apache was being designed, the range of tasks to which the webserver would be applied was unclear, even when the 2.x branch was begun in 2001. Nginx then rather gains in hindsight over its elder forbear – the flexibility so appealing in Apache will likely remain its defining factor, compared to the niche in which Nginx thrives. But there’s more of gravy than of grave about Apache just as yet!

Nginx bless us, every one.

So is Nginx really the best and fastest thing ever? And should I deploy it at once? Maybe. Of course, it matters to analyze what kinds of content you will serve. Static content components of your sites like image and media files, CSS and JavaScript scripts will likely be served faster, either to your cache server if you have one or your end user if you do not, than by only the very latest of Apache releases (2.4.x) – and that translates to a measurable speed increase.

Are there immediate benefits other than speed? Indeed, there are many. More predictable behavior under heavy and rapidly scaling loads, lower memory and CPU requirements and higher concurrency capacity accompany improved static serving times. There’s a lot on offer in the simplest of configurations, even for the most modest of hosts. And with the upstream named server and load balancer directives, FastCGI and memcache caches and a slick, no-connectionsdropped graceful upgrade option there’s much for the sysadmin and devops aficionados amongst you to sink your teeth into too.

Apache 2.4.x’s common Prefork-MPM/mod_php configuration can beat it on speed, but not by much, and that will always cost you both in memory and processor load. Come for the concurrency, stay for the simplified configuration and maintenance.

Should you try it right now? Yes, I think you should. It’s far from immature and there are both guided and automated installation options readily available, including the ones listed here.

If you’re still awake after the pudding and turkey is served, or lost for what to try on after your socks, hats and holiday bathrobe there are many worse ways to waste the time – give it a try while waiting for the Bond movie. You will likely find yourself both speeding up and simplify your serving of HTTP. That should make it a very Merry Christmas, won’t it Tiny Tim. Humbug!

Where can I find more help?

Visit nginx.org/en/docs for the complete directives list.

Benjamin Greenaway has been a software developer for 18 years. After pioneering internet narrowcasting in the 90’s in collaboration with Virtual Futures he has led development on A/V installation projects for Pixar and Sony Entertainment and web applications for SMEs in Southern California before moving to the San Francisco Bay in 2010 and developing performance solutions for Dyn DNS and e-commerce APIs for Tzolkin TZO. He now lives in South London where he balances time writing and developing with the demands of an ever growing collection of retro computers.

 

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -