Nginx 从入门到实践:核心概念、配置解析与常用场景

Nginx 是当今互联网最流行的 Web 服务器之一,同时也能作为反向代理、负载均衡器和 HTTP 缓存。它以高性能、高并发、低内存消耗著称,处理静态文件的能力尤其突出。在这篇博客中,我将带你从 Web 基础概念出发,一步步掌握 Nginx 的安装、核心配置、静态网站部署、反向代理与负载均衡,以及日志管理。无论是初学者还是想系统整理知识的开发者,都能从中受益。

一、Web 服务的核心概念

在深入 Nginx 之前,先理解几个关键概念。

1. HTTP 协议

Web 服务基于 HTTP(超文本传输协议),它是客户端(浏览器)与服务器之间的通信语言。客户端发送请求,服务器返回响应,过程中包含方法(GET、POST 等)、状态码(200、404、500 等)、头部信息和主体内容。

2. Web 服务器

负责接收 HTTP 请求,并根据请求的 URL 返回对应的资源。静态资源(HTML、CSS、图片)直接返回文件内容;动态请求则交由后端程序(如 PHP、Python、Node.js)处理,再将结果返回客户端。Nginx 可以作为独立的静态资源服务器,也能配合后端应用一起工作。

3. 反向代理

正向代理是客户端通过代理服务器访问外部资源,隐藏了客户端。反向代理则是客户端访问代理服务器,代理将请求转发到内部网络中的后端服务器,客户端不知道真正处理请求的机器是谁。Nginx 是最常用的反向代理软件,它还能提供缓存、SSL 终端等附加功能。

4. 负载均衡

当流量增大到单台服务器无法承受时,需要将请求分发到多台后端服务器上,这就是负载均衡。Nginx 通过定义一组上游服务器,并以特定算法(轮询、最少连接、IP 哈希等)将请求转发出去,既能提升整体处理能力,又能实现故障转移。

理解了这些,我们就开始安装和配置 Nginx。

二、Nginx 安装教程

Nginx 支持多种操作系统,这里以最常见的 Ubuntu/Debian 和 CentOS/RHEL 为例。

Ubuntu / Debian 系统

Ubuntu/Debian 的官方仓库版本可能较旧,建议使用 Nginx 官方源。以下命令在终端逐条执行即可。

bash

复制代码
# 安装依赖
sudo apt update
sudo apt install curl gnupg2 ca-certificates lsb-release

# 添加 Nginx 签名密钥和仓库
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

# 安装
sudo apt update
sudo apt install nginx

CentOS / RHEL 系统

bash

复制代码
# 添加 Nginx 官方 YUM 源
sudo yum install yum-utils
sudo tee /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

# 安装
sudo yum install nginx

启动与常用命令

安装完成后,使用以下命令管理 Nginx 服务。这些命令在终端直接运行。

bash

复制代码
# 启动
sudo systemctl start nginx


# 设置开机自启
sudo systemctl enable nginx


# 重新加载配置(不中断服务)
sudo systemctl reload nginx


# 检查配置文件语法
sudo nginx -t

此时访问服务器 IP,应该能看到 Nginx 的默认欢迎页。

三、Nginx 配置文件全解析

Nginx 的主配置文件通常位于 /etc/nginx/nginx.conf(包安装版)或 /usr/local/nginx/conf/nginx.conf(编译安装版)。它的结构采用层次化的块(block)组织,常用的块有:

  • 全局块 (main):影响 Nginx 全局的指令,如用户、工作进程数、错误日志路径等。

  • events 块:配置网络连接相关,比如每个工作进程的最大连接数。

  • http 块 :包含所有 HTTP 服务器相关的配置,可以嵌套多个 server 块。

  • server 块:定义一个虚拟主机,监听某个端口,处理特定域名或 IP 的请求。

  • location 块 :位于 server 内部,根据请求的 URI 匹配不同的处理规则。

来看一个精简后的典型配置示例:

文件:/etc/nginx/nginx.conf(主配置文件)

nginx

复制代码
# 全局块
user  nginx;
worker_processes  auto;          # 自动根据 CPU 核数设置进程数

# 错误日志
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

# events 块
events {
    worker_connections  1024;    # 每个工作进程的最大并发连接数
}

# http 块
http {
    include       /etc/nginx/mime.types;    # 文件扩展名与 MIME 类型映射
    default_type  application/octet-stream;

    # 访问日志格式
    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  /var/log/nginx/access.log  main;

    sendfile        on;          # 高效文件传输
    keepalive_timeout  65;       # 长连接超时

    # 包含其他虚拟主机配置(通常在 conf.d 目录下)
    include /etc/nginx/conf.d/*.conf;

    # 一个 server 块示例
    server {
        listen       80;
        server_name  example.com www.example.com;

        # 字符集
        charset utf-8;

        # 访问日志(可以单独指定)
        access_log  /var/log/nginx/example.access.log  main;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        # 错误页面
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

关键指令解释

  • user nginx:Nginx worker 进程的运行用户,通常设置为 nginx 或 www-data。

  • worker_processes auto:工作进程数量,一般等于 CPU 核心数。

  • worker_connections 1024:每个进程能打开的最大连接数,总最大连接数 = worker_processes × worker_connections。

  • include mime.types:让 Nginx 能根据文件后缀返回正确的 Content-Type。

  • log_format:定义访问日志的格式,可自定义。

  • sendfile on:启用零拷贝模式,提升静态文件传输效率。

所有的配置指令都要以分号 ; 结尾,块用花括号 {} 包裹。修改配置后务必用 nginx -t 检查语法,再执行 systemctl reload nginx

四、部署一个静态网页

部署静态网站是最常见的需求。假设我们的网站文件放在 /var/www/myblog 目录下,其中包含 index.html。我们可以在 /etc/nginx/conf.d/ 下新建一个配置文件 myblog.conf

文件:/etc/nginx/conf.d/myblog.conf

nginx

复制代码
server {
    listen 80;
    server_name myblog.com;    # 换成你的域名或 IP

    root /var/www/myblog;      # 网站根目录
    index index.html index.htm;

    # 日志
    access_log /var/log/nginx/myblog_access.log;
    error_log  /var/log/nginx/myblog_error.log;

    location / {
        try_files $uri $uri/ =404;   # 先尝试文件,再尝试目录,最后 404
    }

    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

解释:

  • root 指定了请求文件时文件系统的起始路径,例如访问 /about.html 会对应 /var/www/myblog/about.html

  • index 定义了默认首页文件。

  • try_files 用来测试文件或目录是否存在,从而决定如何响应。$uri 是当前请求的 URI,$uri/ 会尝试寻找目录下的默认首页,若均不存在则返回 404。

  • 最后一个 location 利用正则匹配 ~ 禁止访问以点开头的隐藏文件,增强安全性。

保存文件后,执行 sudo nginx -t 确认配置正确,然后 sudo systemctl reload nginx,并把域名解析到服务器 IP,即可通过浏览器访问。

五、反向代理

当我们需要将请求转发给后端应用(如 Node.js 运行在 localhost:3000,或 Tomcat 运行在 8080)时,可使用反向代理。只需在 server 或 location 块中使用 proxy_pass

例如,将 api.myblog.com 的请求代理到本地的 Node.js 服务:

文件:/etc/nginx/conf.d/api-proxy.conf(可自定义文件名)

nginx

复制代码
server {
    listen 80;
    server_name api.myblog.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

通过设置这些头信息,后端应用可以获取客户端的真实 IP 和原始请求信息,这对于日志记录和安全验证非常重要。proxy_pass 后面的地址可以是一个 URL,也可以是一个 upstream 组名(见下一节)。

六、负载均衡

Nginx 的负载均衡是通过定义 upstream 块,并在 proxy_pass 中引用实现的。upstream 定义了一组后端服务器,同时可以指定调度算法。

文件:/etc/nginx/conf.d/load-balancer.conf

nginx

复制代码
upstream backend_servers {
    # 默认轮询(round-robin)
    server 192.168.1.10:8080 weight=3;   # weight 权重,比例 3
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 backup;     # 备用服务器,只在所有主服务器不可用时使用
}

server {
    listen 80;
    server_name api.myblog.com;

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

常用调度算法

  • 轮询(默认):按顺序逐一分配。

  • weight:加权轮询,权重越高的服务器被访问的次数越多。

  • ip_hash:根据客户端 IP 的哈希结果分配,同一 IP 的请求固定到同一后端,可解决 session 问题。

  • least_conn:优先分配给当前活动连接数最少的服务器。

  • fair(第三方模块):根据响应时间分配。

通过 server 指令中的 max_failsfail代码_timeout 还可以实现健康检查。将下面这段配置放在上述 upstream 块中即可:

文件:/etc/nginx/conf.d/load-balancer.conf(upstream 块部分)

nginx

复制代码
upstream backend_servers {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}

如果在 fail_timeout 时间内出现了 max_fails 次失败,该服务器会被标记为不可用,直至超时过后再次尝试。

七、Nginx 的访问日志和错误日志

日志是排查问题、分析流量必不可少的工具。

1. 访问日志 (access_log)

记录所有经过 Nginx 的请求,格式可通过 log_format 自定义。默认的 combined 格式类似上面例子中的 main。可以为每个 server 或 location 单独指定访问日志路径及使用的格式,甚至可以使用变量动态生成文件名,实现按天分割:

文件:/etc/nginx/nginx.conf 或单独的 server 块内

nginx

复制代码
# 按天记录访问日志
map $time_iso8601 $log_date {
    "~^(?<ymd>\d{4}-\d{2}-\d{2})" $ymd;
    default                       'date-not-found';
}

access_log /var/log/nginx/access_$log_date.log main;

但更常见的做法是通过日志轮替工具(如 logrotate)来切割日志,避免单个文件过大。

2. 错误日志 (error_log)

记录 Nginx 运行过程中出现的错误、警告、调试信息等。日志级别有:debug, info, notice, warn, error, crit, alert, emerg。通常设置为 warnerror

文件:/etc/nginx/nginx.conf

nginx

复制代码
error_log /var/log/nginx/error.log warn;

3. 关闭日志

如果某个 location 不需要记录访问日志,可使用 access_log off;。例如针对健康检查请求:

文件:任意 server 块内的 location 部分

nginx

复制代码
location /health {
    access_log off;
    return 200 "OK";
}

4. 日志格式变量

常用的日志变量:

  • $remote_addr:客户端 IP

  • $time_local:本地时间

  • $request:完整的请求行

  • $status:响应状态码

  • $body_bytes_sent:发送给客户端的字节数

  • $http_referer:Referer 头

  • $http_user_agent:User-Agent 头

  • $http_x_forwarded_for:代理链 IP

合理配置日志格式,便于后续使用 ELK、GoAccess 等工具进行分析。

结语

从基础的 Web 服务概念到 Nginx 的安装、配置解析,再到静态网站部署、反向代理、负载均衡及日志管理,我们完成了一次完整的 Nginx 实用之旅。Nginx 的灵活和高效远不止于此,它还支持 HTTPS、HTTP/2、流媒体、动态模块等高级功能,值得你在实践中持续深入。

希望这篇博客能够帮助你理清脉络,快速上手 Nginx。开始动手配置属于你的 Web 服务吧!