NOTE

1.1 Nginx

Original Nginx study note: characteristics, configuration, Lua, optimization, general configuration, and FAQ.

Web Servers / NginxUpdated 4 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. What Is Nginx

Nginx is a web server that became well known for addressing the C10K class of concurrency problems. It can be used as:

  • a virtual host server: one machine can host multiple sites;
  • a reverse proxy: requests are forwarded to upstream servers;
  • a load balancer: multiple upstream servers can sit behind the reverse proxy;
  • a cache: responses from upstream services can be cached locally;
  • a static/dynamic split: Nginx can serve static files directly and forward dynamic requests to an application server such as Tomcat.

2. Characteristics

2.1. I/O Multiplexing with epoll

  1. Network I/O can be roughly divided into two phases:

    • wait for data to become ready in the kernel;
    • copy data from kernel space to user space.
  2. Unix I/O models differ in how applications wait for readiness and perform the actual read/write operation. Common models include blocking I/O, non-blocking I/O, I/O multiplexing, and signal-driven/asynchronous mechanisms.

  • Blocking I/O: the call waits until the operation can proceed.
  • Non-blocking I/O: the call returns when it cannot proceed immediately and the application retries later.
  • I/O multiplexing: one event loop can wait for readiness across many file descriptors instead of assigning one thread to every connection.
  • Signal-driven I/O: the operating system notifies the application when an event is ready.
  1. A socket is represented by a file descriptor on Unix-like systems. Nginx can register many connection file descriptors with an event facility such as epoll and process them as events become ready.

  1. select, poll, and epoll are different mechanisms for observing readiness across multiple descriptors. On Linux, Nginx typically uses epoll when available.

2.2. CPU Affinity

A worker can be pinned to specific CPU cores. This can reduce migrations between CPUs and improve cache locality in some workloads. It should be measured rather than treated as a universal tuning requirement.

2.3. sendfile

sendfile can let the kernel transfer file data to a socket with fewer user-space copies, which is useful for static-file serving.

3. Build and Installation

See the source-build note in this category.

4. Configuration

The original note groups most practical Nginx knowledge here.

4.1. Log Configuration

4.1.1. Syntax

A log format is defined with log_format, and access logs are written with access_log.

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

access_log logs/access.log main;

4.1.2. Example

Choose fields that help answer operational questions such as client address, request, status, bytes, user agent, and proxy forwarding information.

4.1.3. References

4.2. Status

4.2.1. Syntax

The stub status module exposes basic connection/request counters.

location = /basic_status {
    stub_status;
}

4.2.2. Example

Restrict the status endpoint to trusted networks if it is enabled outside local development.

4.2.3. References

4.3. HTTP Content Replacement

4.3.1. Syntax

The sub_filter module can replace matching response-body text for supported content types.

sub_filter 'string' 'replacement';
sub_filter_once on;

4.3.2. Example

Use response rewriting only when it is really needed; it couples the proxy layer to response content and can interfere with caching/compression.

4.3.3. References

4.4. Nginx Request Limits

4.4.1. Limit TCP Connections

limit_conn_zone defines the shared state and key, while limit_conn applies the connection limit.

limit_conn_zone $binary_remote_addr zone=conn_zone:10m;

server {
    location /download/ {
        limit_conn conn_zone 1;
    }
}

4.4.2. Limit HTTP Request Rate

limit_req_zone defines a request-rate bucket and limit_req applies it.

limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;

server {
    location /api/ {
        limit_req zone=req_zone burst=5 nodelay;
    }
}

4.5. Nginx Access Control

4.5.1. IP-Based Access Control

allow and deny can restrict access by address.

location /admin/ {
    allow 10.0.0.0/8;
    deny all;
}

Forwarded client-IP headers must be trusted only from known reverse proxies; arbitrary clients can forge X-Forwarded-For.

4.5.2. Login Control

HTTP Basic Authentication can be configured with auth_basic and auth_basic_user_file.

htpasswd -c ./auth_password nginxuser
location /admin/ {
    auth_basic "Restricted";
    auth_basic_user_file $HOME/software/nginx/conf/auth_password;
}

The secure-link module can validate a token/expiration derived from request parameters and a shared secret.

4.6. Nginx as a Static Resource Web Server

4.6.1. gzip

Common options include sendfile, tcp_nopush, tcp_nodelay, and gzip-related directives.

sendfile on;
tcp_nopush on;
gzip on;
gzip_comp_level 4;
gzip_types text/plain text/css application/javascript application/json;

4.6.2. Client Cache

Response headers such as Expires and Cache-Control tell clients how long static resources may be reused.

location ~* \.(png|jpg|jpeg|gif|css|js)$ {
    expires 7d;
}

4.6.3. Cross-Origin Access

CORS response headers can be added when a resource is intentionally shared across origins. The origin/method/header policy should be as narrow as the application needs.

The valid_referers directive can be used as a lightweight hotlinking control, although the Referer header is not a strong authentication mechanism.

4.7. Nginx as a Proxy Service

4.7.1. Forward / Reverse Proxy

The original note focuses on reverse proxying: the client talks to Nginx, and Nginx talks to an upstream service.

location /api/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
}

4.7.2. Load Balancing

An upstream block groups backend servers.

upstream app_backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
}

server {
    location / {
        proxy_pass http://app_backend;
    }
}

Nginx supports strategies such as round robin, weights, hashing, and health/failure handling depending on configuration and edition/modules.

4.7.3. Server Cache

A reverse proxy can cache upstream responses.

proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=ngx_cache:10m max_size=10g inactive=60m use_temp_path=off;

location / {
    proxy_cache ngx_cache;
    proxy_cache_valid 200 304 12h;
    proxy_cache_valid any 10m;
    proxy_pass http://app_backend;
}

Caching rules must account for authentication, cookies, Vary, request methods, and application-specific correctness.

4.7.4. Static/Dynamic Split

Serve static resources directly from Nginx and proxy application requests to the backend when that separation fits the deployment.

4.8. rewrite Rules

4.8.1. Syntax

rewrite changes a URI using a regular expression and replacement.

rewrite regex replacement [flag];

Flags such as last, break, redirect, and permanent have different control-flow behavior.

4.8.2. Example

location /test/ {
    rewrite ^/test/(.*)$ /$1 break;
}

4.8.3. References

4.9. Configure HTTPS

4.9.1. Syntax

Modern Nginx enables TLS on the listen directive. The old ssl on; directive has been removed.

listen 443 ssl;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_protocols TLSv1.2 TLSv1.3;

4.9.2. Example

For a local self-signed test certificate:

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
server {
    listen 443 ssl;
    server_name 127.0.0.1;
    ssl_certificate $HOME/software/code/server.crt;
    ssl_certificate_key $HOME/software/code/server.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    index index.html;
    location / {
        root $HOME/software/code;
    }
}

4.9.3. References

5. LUA

5.1. Processing Phases

OpenResty/lua-nginx-module exposes hooks at multiple Nginx request-processing phases.

5.2. Lua API

5.3. Example

location /hello {
    default_type 'text/plain';
    content_by_lua 'ngx.say("Hello, Lua")';
}

location /myip {
    default_type 'text/plain';
    content_by_lua '
        local headers = ngx.req.get_headers()
        ngx.say("X-Forwarded-For:", headers["x_forwarded_for"] or "")
    ';
}

location /dep {
    content_by_lua_file $HOME/software/code/dep.lua;
}

Do not treat arbitrary X-Forwarded-For input as a trusted client address unless the immediate proxy is trusted and Nginx is configured to parse trusted forwarding headers.

6. Optimization

6.1. CPU Affinity

The original note shows explicit worker-to-core masks. Modern Nginx can also use:

worker_processes auto;
worker_cpu_affinity auto;

CPU affinity is a tuning option, not a requirement; validate it with measurements.

6.2. File Descriptors

High-concurrency servers may need sufficient process and operating-system file-descriptor limits.

worker_rlimit_nofile 65535;

events {
    worker_connections 10240;
}

The effective maximum is still bounded by OS limits, upstream connections, memory, and workload characteristics.

7. General Configuration

A representative configuration keeps global, events, and http settings separated and includes per-site files when appropriate.

worker_processes auto;

events {
    worker_connections 10240;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    keepalive_timeout 65;
    include conf.d/*.conf;
}

8. FAQ

8.1. Priority When One server Has Multiple location Blocks

Nginx location matching distinguishes exact matches, prefix matches, and regular-expression locations. The detailed precedence rules matter when multiple locations can match the same URI.

8.2. Priority of Multiple Identical server_name Values

Avoid ambiguous duplicate server_name definitions in the same listen context. The selected virtual server depends on listen address/port, hostname matching, and default-server rules.

8.3. Difference Between root and alias

root appends the request URI to the configured path. alias replaces the matched location prefix with the configured filesystem path.

location /static/imgs/ {
    root $HOME;
}

location /images/ {
    alias $HOME/static/imgs/;
}

8.4. Get the Real Client IP

When Nginx is behind a trusted reverse proxy, configure the Real IP module with trusted proxy ranges and the header used by that proxy. Do not trust client-supplied forwarding headers from arbitrary networks.

8.5. try_files

try_files checks files/directories in order and internally redirects to the final fallback when nothing matches.

location / {
    root $HOME/software/nginx/cache;
    try_files $uri $uri/ @java_page;
}

location @java_page {
    proxy_pass http://127.0.0.1:9090;
}

8.6. Common Error Codes

  • 413: request body exceeds the configured body-size limit, commonly client_max_body_size.
  • 502: Nginx could not get a valid response from the upstream.
  • 504: upstream response timed out.

9. References

Loading helpful count