Skip to content

Nginx

一、Nginx 基础

1. Nginx 是什么?

Nginx 是一个高性能的 Web 服务器和反向代理服务器。

核心特性:

  • 高性能 - 高并发、低内存占用
  • 反向代理 - 负载均衡、请求转发
  • 静态文件服务 - 高效提供静态资源
  • SSL/TLS 终止 - HTTPS 支持
  • 模块化 - 丰富的功能模块

2. Nginx vs Apache

特性NginxApache
并发模型事件驱动多进程/多线程
内存占用较高
静态文件性能优秀性能良好
动态内容需要反向代理原生支持
配置相对简单功能丰富但复杂
适用场景高并发、反向代理传统 Web 应用

3. Nginx 应用场景

  • Web 服务器 - 提供静态文件
  • 反向代理 - 转发请求到后端服务
  • 负载均衡 - 分发请求到多个服务器
  • API 网关 - 统一入口
  • SSL 终止 - HTTPS 处理

二、文件结构

  • Linux: /etc/nginx/nginx.conf 或 /usr/local/nginx/conf/nginx.conf
  • Windows: nginx/conf/nginx.conf

二、基本配置

# 全局块
user  nginx;            # 工作进程的用户
worker_processes  auto; # 工作进程数(通常设为CPU核心数)
error_log  /var/log/nginx/error.log; # 错误日志
pid        /var/run/nginx.pid;       # PID 文件路径

# events 块:影响 Nginx 与客户端的连接方式
events {
    worker_connections  1024;  # 每个进程最大连接数
    use epoll;                 # Linux 下推荐使用 epoll 提升性能
}

# http 块:核心配置,包含大多数 Web 服务配置
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;       # 高效传输文件
    tcp_nopush      on;       # 提升网络效率
    keepalive_timeout  65;    # 长连接超时时间
    gzip  on;                 # 开启 Gzip 压缩

    # server 块:虚拟主机配置(可有多个)
    server {
        listen       80;                      # 监听端口
        server_name  localhost;              # 域名

        # location 块:匹配请求路径
        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;
        }
    }
}

三、常用功能配置示例

1、静态资源服务器

server {
    listen 80;
    server_name static.example.com;

    location / {
        root /var/www/static;
        index index.html;
        expires 1y;            # 缓存1年
        add_header Cache-Control "public, immutable";
    }

    # 图片、JS、CSS 缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public";
    }
}

2. 反向代理(Reverse Proxy)

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

    location / {
        proxy_pass http://localhost:5000;  # 转发到本地5000端口
        proxy_http_version 1.1;
        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;
    }
}

3. 负载均衡(Load Balancing)

upstream backend {
    # 轮询(默认)
    server 192.168.1.10:5000;
    server 192.168.1.11:5000;

    # 权重
    # server 192.168.1.10:5000 weight=3;
    # server 192.168.1.11:5000 weight=1;

    # IP 哈希(会话保持)
    # ip_hash;

    # 最少连接
    # least_conn;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
    }
}

4. HTTPS / SSL 配置

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;

    location / {
        root /var/www/html;
        index index.html;
    }
}

# HTTP 强制跳转 HTTPS
server {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;
}

5. 跨域配置

location /api/ {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    proxy_pass http://localhost:5000;
}

6. 常用命令

# 启动 Nginx
nginx

# 停止
nginx -s stop      # 快速停止
nginx -s quit      # 优雅关闭

# 重新加载配置(热更新)
nginx -s reload

# 重启
systemctl restart nginx

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

# 查看版本
nginx -v

7. 访问控制

基于 IP 的访问控制(allow / deny)

  • 语法
allow  address | CIDR | all;
deny   address | CIDR | all;
  • 示例 1:只允许内网访问管理后台
location /admin/ {
    # 只允许 192.168.1.0/24 网段访问
    allow 192.168.1.0/24;
    # 允许本地访问
    allow 127.0.0.1;
    # 拒绝所有其他 IP
    deny all;

    root /var/www/html;
    index index.html;
}
  • 示例 2:禁止某个 IP 访问
location / {
    # 禁止恶意 IP
    deny  192.168.1.100;
    deny  203.0.113.50;
    # 允许其他所有
    allow all;

    proxy_pass http://backend;
}
  • 注意
  • llow 和 deny 的顺序很重要,Nginx 会按顺序匹配,第一个匹配的规则生效。
  • 通常把 deny all 放在最后。
  • 支持 IPv4 和 IPv6。

基于 Referer 的访问控制(防盗链)

  • 防止其他网站直接引用你的静态资源(如图片、JS、CSS)。

  • 示例:只允许本站和百度搜索访问图片

location ~* \.(jpg|jpeg|png|gif|ico)$ {
    # 有效的来源
    valid_referers none blocked server_names
                   *.baidu.com *.google.com;

    # 如果 referer 不在白名单,返回 403 或替换图片
    if ($invalid_referer) {
        # 方法1:返回403
        # return 403;

        # 方法2:返回默认图片(更友好)
        rewrite ^/.*$ /images/forbidden.jpg last;
    }

    expires 1y;
    add_header Cache-Control "public";
}
  • valid_referers:定义合法的来源。
  • $invalid_referer:变量,为 1 表示 referer 无效。

四、性能优化

1. 工作进程优化

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

# 每个进程最大连接数
events {
    worker_connections 1024;
    use epoll;  # Linux 下使用 epoll
}

2. 缓存优化

nginx
# 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;

server {
    location / {
        proxy_cache my_cache;
        proxy_cache_valid 200 60m;
        proxy_cache_valid 404 1m;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        
        proxy_pass http://backend;
    }
}

3. Gzip 压缩

nginx
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;

4. 连接优化

nginx
keepalive_timeout 65;
keepalive_requests 100;
tcp_nopush on;
tcp_nodelay on;

五、安全配置

1. 隐藏 Nginx 版本

nginx
server_tokens off;

2. 限制请求大小

nginx
client_max_body_size 10m;
client_body_buffer_size 128k;

3. 防止 DDoS

nginx
# 限制连接数
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_conn conn_limit_per_ip 10;

# 限制请求速率
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
limit_req zone=req_limit_per_ip burst=20 nodelay;

4. 安全头

nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

六、日志管理

1. 访问日志

nginx
log_format detailed '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time';

access_log /var/log/nginx/access.log detailed;

2. 错误日志

nginx
error_log /var/log/nginx/error.log warn;

3. 日志轮转

bash
# 使用 logrotate
/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

七、常见面试题

Q1: Nginx 如何处理高并发?

  1. 事件驱动模型 - 使用 epoll(Linux)处理大量连接
  2. 多进程架构 - 主进程 + 多个工作进程
  3. 非阻塞 I/O - 异步处理请求
  4. 内存池 - 减少内存分配开销

Q2: Nginx 负载均衡算法?

  1. 轮询(Round Robin) - 默认,依次分配
  2. 权重(Weight) - 按权重分配
  3. IP 哈希(ip_hash) - 同一 IP 总是路由到同一服务器
  4. 最少连接(least_conn) - 分配到连接数最少的服务器
  5. fair - 按响应时间分配(需要第三方模块)

Q3: Nginx 反向代理和正向代理的区别?

反向代理:

  • 代理服务器端
  • 客户端不知道真实服务器
  • 用于负载均衡、隐藏服务器

正向代理:

  • 代理客户端
  • 服务器不知道真实客户端
  • 用于翻墙、缓存

Q4: 如何实现 Nginx 高可用?

  1. Keepalived - 实现虚拟 IP 漂移
  2. 多实例部署 - 多个 Nginx 实例
  3. 健康检查 - 监控后端服务状态
  4. 自动故障转移 - 主节点故障时切换到备用节点

Q5: Nginx 如何实现灰度发布?

nginx
upstream backend {
    server 192.168.1.10:5000 weight=90;  # 90% 流量
    server 192.168.1.11:5000 weight=10;  # 10% 流量(新版本)
}

八、最佳实践

  1. 合理配置工作进程 - 通常设为 CPU 核心数
  2. 启用 Gzip 压缩 - 减少传输大小
  3. 使用缓存 - 提升性能
  4. 配置日志 - 便于排查问题
  5. 安全配置 - 隐藏版本、限制请求
  6. 监控 - 监控连接数、请求速率
  7. 定期更新 - 保持最新版本
  8. 测试配置 - 修改后先测试
  9. 不要忽略错误日志 - 及时发现问题
  10. 不要过度优化 - 根据实际需求配置

基于 VitePress 构建 | Copyright © 2026-present