本文最后更新于 2025-02-12,墨迹未干时,知识正鲜活。随着时间推移,文章部分内容可能需要重新着墨,请您谅解。Contact

Nginx

Nginx 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 电子邮件代理服务器。它因其高并发连接数和强大的负载均衡能力而广受欢迎。本博文将从基本介绍、功能说明到配置文件的结构和设置,最后辅以一些常见问题解决方案来讲解 Nginx。

先把Nginx常用命令常用命令放在这里以便查询:

  • 启动 Nginx

    sudo systemctl start nginx
    
  • 停止 Nginx

    sudo systemctl stop nginx
    
  • 重启 Nginx

    sudo systemctl restart nginx
    
  • 重新加载配置文件(不重启服务)

    sudo nginx -s reload
    
  • 查看 Nginx 状态

    sudo systemctl status nginx
    
  • 查看 Nginx 日志

    • 错误日志:
      sudo tail -f /var/log/nginx/error.log
      
    • 访问日志:
      sudo tail -f /var/log/nginx/access.log
      

一. Nginx 的基本功能

  1. Web 服务器
    用于提供静态文件(如 HTML、CSS、JS、图片等)的访问,性能优于 Apache。

  2. 反向代理和负载均衡
    能够将客户端的请求转发到后端服务器(例如 Node.js、Python 应用等),并支持多种负载均衡算法。

  3. 缓存功能
    支持 FastCGI、代理缓存及静态资源缓存。

  4. 支持 HTTPS
    可以与 OpenSSL 集成,以支持 SSL/TLS 加密的网站访问。

  5. 支持动态模块
    通过加载模块扩展功能,例如 WAF(Web 应用防火墙)。

  6. 流处理
    可用于 TCP/UDP 流量的处理。

  7. 访问控制
    基于 IP 地址,甚至 User-Agent,提供细粒度访问控制。


二. Nginx 配置文件结构

Nginx 的配置文件通常是一个主配置文件,按模块和功能划分为多个“块”,并支持通过 include 语句引用其它子配置文件。

主配置文件路径

一般安装后的主配置文件路径为 /etc/nginx/nginx.conf,也可能会有所不同(根据安装方式和平台)。

配置文件的整体结构

Nginx 配置文件采用嵌套的层级结构,由多个模块组成,各个模块通常对应特定的功能。主要分为以下几个部分:

  1. 全局块
    设置影响整个 Nginx 的运行参数,比如用户权限、进程数、错误日志、模块加载等。

  2. 事件块
    设置与网络连接、请求处理相关的参数,比如并发连接、网络模型等。

  3. http 块(服务块):
    是最核心的部分,具体包括反向代理、负载均衡和静态文件服务的配置。

  4. server 块
    每个 server 块定义一个虚拟主机,也就是对应一个域名。

  5. location 块
    locationserver 的子块,用于匹配特定的 URL 路由规则。


三. 主要配置及结构详解

1. 全局块

定义影响整个 Nginx 服务的通用配置。

user nginx;          # 指定 Nginx 的运行用户
worker_processes auto;  # 工作进程的数量,通常设为服务器 CPU 核心数
error_log /var/log/nginx/error.log warn;  # 错误日志级别及路径
pid /var/run/nginx.pid;  # Nginx 的 PID 文件路径

2. 事件块

设置服务器处理网络连接的相关参数。

events {
    worker_connections 1024;  # 每个 worker 进程支持的最大连接数
    use epoll;                # 使用的网络模型(Linux 推荐 epoll)
    multi_accept on;          # 是否同时接受多个新连接
}

3. http 块

这是主要的配置块,包含多种 HTTP 服务功能的子配置。包括 MIME 类型设置、日志格式、Gzip 压缩等。

http {
    include       /etc/nginx/mime.types;    # 定义 MIME 类型文件的路径
    default_type  application/octet-stream;  # 默认 MIME 类型
    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;                  # 连接保持时间
    gzip on;                                # 开启 Gzip 压缩
}

4. server 块

表示一个虚拟主机(可以设定域名和端口等)。一个 http 块中可以包含多个 server,每个 server 负责处理一个域名或 IP 地址。

server {
    listen 80;                             # 监听端口
    server_name example.com www.example.com; # 当前 server 对应的域名

    root /var/www/html;                    # 指定网站文件根目录
    index index.html index.htm;            # 默认首页文件
}

5. location 匹配块

定义 URL 路径的路由规则,并设定如何处理这些路径下的请求。

server {
    listen 80;
    server_name example.com;

    location / {                            # 匹配根路径
        try_files $uri $uri/ =404;          # 优先查找文件/目录
    }
  
    location /images/ {                     # 匹配 /images/ 开头的路径
        root /data;                         # 图片资源来自 /data/images/ 目录
    }
  
    location ~ \.php$ {                     # 匹配 .php 结尾的文件(正则匹配)
        include fastcgi_params;             # 加载 fastcgi 参数文件
        fastcgi_pass 127.0.0.1:9000;        # PHP-FPM 服务地址
        fastcgi_index index.php;            # 默认 PHP 入口文件
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
    }
}
说明:
  1. 可以使用 前缀字符串正则表达式 匹配 URL,比如:
    • =:精确匹配。
    • ~:区分大小写的正则匹配。
    • ~*:不区分大小写的正则匹配。
    • ^~:优先匹配前缀字符串,而不去检查正则表达式。
  2. 常见指令
    • proxy_pass:用于反向代理请求。
    • root:指定根目录。
    • rewrite:URL 重写。
    • return:直接返回响应码或内容。

四. 子配置文件及引用

Nginx 提供文件分离管理的方式,使用 include 子配置文件。

常见的文件结构

/etc/nginx/
├── nginx.conf                   # 主配置文件
├── mime.types                   # MIME 类型配置文件
├── conf.d/                      # 存放通用配置
│   ├── default.conf             # 默认 server 块配置
│   ├── ssl.conf                 # TLS/SSL 相关配置
├── sites-available/             # 网站配置目录
│   ├── example.com.conf         # 虚拟主机配置
└── sites-enabled/               # 活动站点配置链接
    └── example.com.conf         # 软链接到 sites-available

使用主配置文件引入子配置

/etc/nginx/nginx.conf 包括子配置文件:

http {
    include /etc/nginx/conf.d/*.conf;       # 加载 conf.d 目录下所有文件
    include /etc/nginx/sites-enabled/*;     # 加载启用的站点配置
}

五. 常见功能配置示例

1. 反向代理

location /api/ {
    proxy_pass http://backend.local:8080;   # 将请求代理到后端
    proxy_set_header Host $host;           # 设置请求头
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

2. 负载均衡

upstream backend {
    server 192.168.1.101;
    server 192.168.1.102;
}

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

3. HTTPS 配置

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
}

六. 常见问题及解决方法

1. Nginx 启动失败

  • 问题描述:启动 Nginx 时出现错误,无法启动服务器。

  • 解决办法

    • 检查配置文件语法

      sudo nginx -t
      

      根据提示修正语法错误。

    • 检查端口占用

      sudo lsof -i :80
      

      如果端口被占用,停止相关进程或更改 Nginx 的监听端口。

    • 查看错误日志
      检查 /var/log/nginx/error.log 获取详细错误信息。

2. 无法访问 PHP 文件

  • 问题描述:在浏览器中访问 PHP 文件时,显示下载文件或 404 错误。

  • 解决办法

    • 确认 PHP-FPM 是否运行

      sudo systemctl status php-fpm
      

      如果未运行,启动 PHP-FPM:

      sudo systemctl start php-fpm
      
    • 检查 Nginx 配置中的 PHP 相关部分
      确保 fastcgi_pass 指向正确的 PHP-FPM 地址和端口,例如 127.0.0.1:9000 或使用 Unix 套接字 unix:/run/php/php7.4-fpm.sock;

    • 验证 SCRIPT_FILENAME 参数

      fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
      

      确保路径正确,且 Nginx 用户有权限访问 PHP 文件。

3. Nginx 加载静态文件缓慢

  • 问题描述:网站加载速度慢,静态资源加载缓慢。

  • 解决办法

    • 启用 Gzip 压缩
      http 块中添加或确认以下配置:

      gzip on;
      gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
      gzip_min_length 256;
      
    • 使用浏览器缓存
      location 块中设置缓存头:

      location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
          expires 30d;
          add_header Cache-Control "public, no-transform";
      }
      
    • 启用 sendfile
      确认在 http 块中设置 sendfile on;,这可以提高文件传输效率。

    • 优化 worker_processesworker_connections
      根据服务器硬件调整这些参数以处理更多并发连接。

4. HTTPS 配置问题

  • 问题描述:HTTPS 网站无法正常访问,或浏览器提示安全错误。

  • 解决办法

    • 检查 SSL 证书路径和权限
      确保 ssl_certificatessl_certificate_key 指向正确的文件,并且 Nginx 有权限读取。

    • 验证配置语法

      sudo nginx -t
      
    • 开放防火墙的 443 端口

      sudo ufw allow 443
      
    • 使用可信的证书
      推荐使用 Let's Encrypt 获取免费且可信的 SSL 证书:

      sudo apt install certbot python3-certbot-nginx
      sudo certbot --nginx -d example.com -d www.example.com
      

5. 反向代理后端服务器不可达

  • 问题描述:配置了反向代理后,无法访问后端服务器的服务。

  • 解决办法

    • 确认后端服务器地址和端口正确,且后端服务正在运行。

    • 检查防火墙设置,确保 Nginx 可以访问后端服务器的端口。

    • 查看 Nginx 错误日志,获取具体错误信息:

      sudo tail -f /var/log/nginx/error.log
      
    • 确保 proxy_pass 使用正确的协议(http 或 https)和地址。

6. Nginx 重启后配置未生效

  • 问题描述:修改 Nginx 配置后重启无效,配置未生效。

  • 解决办法

    • 检查配置文件是否有语法错误

      sudo nginx -t
      
    • 确认正在编辑的配置文件是 Nginx 使用的文件,通过以下命令查看 Nginx 的编译参数:

      nginx -V
      
    • 确保没有多个 Nginx 实例在运行,避免配置冲突:

      ps aux | grep nginx
      
    • 正确重启 Nginx

      sudo systemctl restart nginx
      

      sudo service nginx restart
      

七. 性能优化建议

1. 调整 Worker 进程和连接数

  • 根据服务器硬件调整 worker_processesworker_connections
    worker_processes auto;
    events {
        worker_connections 4096;
        multi_accept on;
        use epoll;
    }
    
    worker_processes 通常设置为服务器的 CPU 核心数,worker_connections 根据需要调整以处理更多并发连接。

2. 启用 HTTP/2

  • 提高 HTTPS 连接性能,在 server 块中启用 HTTP/2:
    server {
        listen 443 ssl http2;
        server_name example.com;
    
        ssl_certificate     /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
    
        # 其余配置...
    }
    

3. 使用缓存

  • FastCGI 缓存

    http {
        fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=FCGI:100m inactive=60m;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
      
        server {
            location ~ \.php$ {
                fastcgi_cache FCGI;
                fastcgi_cache_valid 200 60m;
                fastcgi_pass 127.0.0.1:9000;
                # 其他 FastCGI 设置...
            }
        }
    }
    
  • 代理缓存

    http {
        proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=ZONE:10m inactive=60m;
    
        server {
            location /api/ {
                proxy_cache ZONE;
                proxy_pass http://backend.local:8080;
                # 其他代理设置...
            }
        }
    }
    

八. 安全配置建议

1. 限制访问权限

  • 禁止访问敏感文件和目录:
    location ~ /\.(ht|git|svn) {
        deny all;
    }
    

2. 防止 DDoS 攻击

  • 限制连接数和请求速率
    http {
        limit_conn_zone $binary_remote_addr zone=addr:10m;
        limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
      
        server {
            location / {
                limit_conn addr 10;
                limit_req zone=req burst=20 nodelay;
            }
        }
    }
    

3. 隐藏 Nginx 版本信息

  • http 块中设置隐藏版本信息:
    http {
        server_tokens off;
        # 其他配置...
    }
    

4. 使用安全头部

  • 添加安全相关的 HTTP 头:
    server {
        add_header X-Frame-Options "DENY";
        add_header X-Content-Type-Options "nosniff";
        add_header X-XSS-Protection "1; mode=block";
        # 其他配置...
    }
    

九. 其他常用工具和资源

1. Let's Encrypt

  • 使用 Certbot 获取免费 SSL 证书,简化 HTTPS 配置:
    sudo apt install certbot python3-certbot-nginx
    sudo certbot --nginx -d example.com -d www.example.com
    

2. 监控与日志分析

  • GoAccess:实时分析 Nginx 访问日志,生成可视化报告:

    sudo apt install goaccess
    goaccess /var/log/nginx/access.log -c
    
  • Grafana 与 Prometheus:结合 Nginx Exporter,实现全面的监控与告警。

3. 自动化部署

  • Git 与 CI/CD 工具:使用 Git 与 Jenkins、GitLab CI 等工具,实现 Nginx 配置和网站内容的自动部署。

  • 配置管理工具:使用 Ansible、Chef 或 Puppet 管理 Nginx 配置,确保一致性和可重复性。