Skip to content

深入理解 Nginx 配置结构与 server 块

本文是 Nginx 实操专栏的第二篇,我们将深入探讨 Nginx 的配置文件结构和 server 块的配置细节,帮助你掌握如何正确配置虚拟主机和处理不同的域名请求。

引言

在上一篇文章中,我们介绍了 Nginx 的整体架构和工作原理。今天,我们将深入研究 Nginx 的配置文件结构,特别是 server 块的配置细节。理解这些内容对正确配置虚拟主机、处理不同域名请求至关重要。

Nginx 配置文件结构详解

Nginx 的配置文件遵循特定的结构,每一部分都有其特定的作用域和功能。

配置文件的基本结构

nginx
# 全局块
...

# events 块
events {
    ...
}

# http 块
http {
    # http 全局块
    ...
    
    # server 块
    server {
        ...
    }
    
    # 可以有多个 server 块
    server {
        ...
    }
}

全局块配置

全局块位于配置文件的最外层,影响整个 Nginx 服务器的行为:

nginx
# 工作进程数,通常设置为 CPU 核心数
worker_processes auto;

# 错误日志位置和级别
error_log /var/log/nginx/error.log warn;

# 进程 PID 文件位置
pid /var/run/nginx.pid;

# 包含其他配置文件
include /etc/nginx/modules-enabled/*.conf;

events 块配置

events 块用于配置 Nginx 的事件处理模型:

nginx
events {
    # 每个工作进程的最大连接数
    worker_connections 1024;
    
    # 使用的事件模型(根据操作系统自动选择)
    use epoll;
    
    # 是否允许多个连接同时接受
    multi_accept on;
    
    # 是否启用内核套接字参数调试
    debug_connection 127.0.0.1;
}

http 块配置

http 块是配置 HTTP 服务器的主要区域,包含 http 全局配置和多个 server 块:

nginx
http {
    # MIME 类型映射
    include /etc/nginx/mime.types;
    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;
    
    # 是否发送 nginx 版本号
    server_tokens off;
    
    # 文件传输相关配置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # 连接超时时间
    keepalive_timeout 65;
    
    # Gzip 压缩配置
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript;
}

server 块详解

server 块是配置虚拟主机的关键部分,每个 server 块代表一个虚拟主机。

基本 server 块配置

nginx
server {
    # 监听端口和地址
    listen 80;
    listen [::]:80;  # IPv6 支持
    
    # 服务器名称(域名)
    server_name example.com www.example.com;
    
    # 根目录
    root /var/www/example.com;
    
    # 默认首页文件
    index index.html index.htm;
    
    # 访问日志(可选,覆盖全局设置)
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

server_name 指令详解

server_name 指令用于指定虚拟主机的域名,支持多种匹配方式:

精确匹配

nginx
server_name example.com;

通配符匹配

nginx
# 匹配所有以 .example.com 结尾的域名
server_name *.example.com;

# 匹配所有以 www. 开头的域名
server_name www.*;

正则表达式匹配

nginx
# 使用波浪号开头表示正则表达式
server_name ~^www\d+\.example\.com$;

混合配置

nginx
server {
    server_name example.com *.example.com www.example.*;
    
    # 处理没有匹配到任何 server 块的情况
    listen 80 default_server;
}

匹配优先级顺序:

  1. 精确匹配
  2. 以 * 开头的最长通配符(如 *.example.com)
  3. 以 * 结尾的最长通配符(如 mail.*)
  4. 第一个匹配的正则表达式
  5. default_server 标记的 server 块

listen 指令详解

listen 指令用于指定监听的地址和端口:

nginx
# 监听特定 IP 和端口
listen 192.168.1.1:80;

# 监听所有地址的 80 端口
listen 80;

# 监听 IPv6 地址
listen [::]:80;

# HTTPS 配置
listen 443 ssl http2;

# 设置为默认服务器
listen 80 default_server;

# 仅接受 IPv6 连接
listen [::]:80 ipv6only=on;

实际应用示例

多域名虚拟主机配置

nginx
# 主网站
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;
}

# 博客子域名
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.html;
}

# API 子域名
server {
    listen 80;
    server_name api.example.com;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

HTTP 重定向到 HTTPS

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    
    # 将所有 HTTP 请求重定向到 HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL 证书配置
    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;
    
    root /var/www/example.com;
    index index.html;
}

基于端口的虚拟主机

nginx
# 默认网站
server {
    listen 80;
    server_name _;
    root /var/www/default;
}

# 管理后台
server {
    listen 8080;
    server_name admin.example.com;
    root /var/www/admin;
}

高级配置技巧

变量的使用

Nginx 提供了许多内置变量,可以在配置中使用:

nginx
server {
    listen 80;
    server_name example.com;
    
    # 使用变量记录详细的访问日志
    log_format detailed '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $body_bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       '"$host" "$request_time"';
    
    access_log /var/log/nginx/detailed.log detailed;
    
    # 根据 User-Agent 返回不同内容
    location / {
        if ($http_user_agent ~* Chrome) {
            root /var/www/chrome;
        }
        root /var/www/default;
    }
}

错误页面自定义

nginx
server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;
    
    # 自定义错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    
    location = /404.html {
        internal;
    }
    
    location = /50x.html {
        internal;
    }
}

最佳实践

配置组织

为了便于管理和维护,建议将配置文件组织如下:

/etc/nginx/
├── nginx.conf              # 主配置文件
├── conf.d/                 # 通用配置
│   ├── gzip.conf
│   └── security.conf
├── sites-available/        # 可用站点配置
│   ├── default
│   ├── example.com
│   └── api.example.com
└── sites-enabled/          # 启用站点的符号链接
    ├── default -> ../sites-available/default
    └── example.com -> ../sites-available/example.com

安全配置

nginx
server {
    listen 80;
    server_name example.com;
    
    # 隐藏版本信息
    server_tokens off;
    
    # 防止 iframe 嵌入
    add_header X-Frame-Options DENY;
    
    # 防止 MIME 类型嗅探
    add_header X-Content-Type-Options nosniff;
    
    # 启用 XSS 过滤
    add_header X-XSS-Protection "1; mode=block";
}

配置测试与重载

在修改配置文件后,务必进行测试:

bash
# 测试配置文件语法
nginx -t

# 重新加载配置(不停机)
nginx -s reload

# 查看 Nginx 状态
systemctl status nginx

总结

掌握 Nginx 配置文件结构和 server 块的配置是使用 Nginx 的基础。通过合理配置虚拟主机,我们可以轻松地在同一台服务器上托管多个网站或应用。

在下一章中,我们将深入探讨 location 块的匹配规则和代理配置,这是 Nginx 最强大和复杂的功能之一。

要点回顾:

  1. Nginx 配置分为全局块、events 块和 http 块三个层次
  2. server 块用于配置虚拟主机,通过 server_name 和 listen 指令区分
  3. server_name 支持精确匹配、通配符匹配和正则表达式匹配
  4. 合理组织配置文件有助于维护和管理
  5. 配置修改后需要测试并重新加载才能生效