Tuesday, June 26, 2018

Serving Static Content


Overview on `root` directive
----------------------------

- specifies directory to search for files (similar to DocumentRoot in apache)
- can be placed within level of http, server, or location contexts


server {
    root /www/data;
      # determines root directory for the 1st 2 locations

    location / {
    }

    location /images/ {
    }

    location ~ \.(mp3|mp4) {
        root /www/media;
          # this location specifies its own root directory
    }
}

Using index files
-----------------

- if requested URI ends with `/` such as http://webserver.com/images/, nginx
  treats the request as a request for directory and tries to look for an index
  file
- `index` directive determines the filename of the index file
  (default: index.html)
- if nginx cannot see an index file, it returns "HTTP Code 404"


prevents returning HTTP code 404
(if file is not found) and return
a directory listing instead
location /images/ {
    autoindex on;
}
lists more than 1 filename for
index file (searches them in order)
location / {
    index index.$geo.html index.htm index.html;
      # `$geo` value depends on client's address
}
if index.html is not found but
index.php is there, the request will be
proxied
location / {
    root /data;
    index index.html index.php;
}

location ~ \.php {
    fastcgi_pass localhost:8000;
    ...
}


Trying Several Options
----------------------

- this done by using `try_files` directive

serves default.gif if the file
requested by URI is not found
server {
    root /www/data;
    location /images/ {
        try_files $uri /images/default.gif;
    }
}
returns an error code if any
of the given options doesn't
resolve the issue
location / {
    try_files $uri $uri/ $uri.html =404;
}
redirect you to a backend
server when the requested file
is not found
location / {
    try_files $uri $uri/ @backend;
}
location @backend {
    proxy_pass http://backend.example.com;
}


Optimizing Speed for Static Content
-----------------------------------

Enabling sendfile

 - nginx handles file transmission itself
 - by default, it copies file into buffer
   before sending
 - enabling sendfile prevents buffering
 - sendfile enables direct copying from
   one file descriptor to another
location /mp3 {
    sendfile           on;
      # enables sendfile

    sendfile_max_chunk 1m;
      # limits file size handled by sendfile
    ...
}
Enabling tcp_nopush

 - enables nginx to send HTTP response
   headers in one packet right after the
   chunk of data has been obtained by
   sendfile
location /mp3 {
    sendfile   on;
    tcp_nopush on;
    ...
}
Enabling tcp_nodelay

 - this disables Nagle's algorithm
 - Nagle's algorithm are for slow
   connections only; consolidates a
   number of small packets into a larger
   one and sends it in 200ms delay
 - by default, `tcp_nodelay` is set to on
   meaning Nagle's algorithm is disabled
location /mp3  {
    tcp_nodelay       on;
    keepalive_timeout 65;
    ...
}
Optimizing backlog queue

 - general rule is when a connection is
   established, it is put into "listen"
   queue of a listen socket

to measure current listen queue:
netstat -Lan

example output:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen         Local Address        
0/0/128        *.12345           
10/0/128        *.80      
0/0/128        *.8080

output above tells us that there is 10 unaccepted connections
while having a maximum connection limit of 128

if the output is like this:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen         Local Address        
0/0/128        *.12345           
192/0/128        *.80      
0/0/128        *.8080

the unaccepted connection is greater than the limit which is
common when the website is experiencing heavy traffic

to increase the limit on OS side:
echo 'net.core.somaxconn = 4096' > /etc/sysctl.conf
sysctl -p

then increase the limit on Nginx side afterwards:
server {
    listen 80 backlog 4096;
    # reload nginx after this change
 ...
}

No comments:

Post a Comment