6.Nginx 服务器技术手册(CentOS 7 版)

Nginx 服务器技术手册

CentOS 7 版

文章目录

  • [Nginx 服务器技术手册](#Nginx 服务器技术手册)
  • [1. Nginx 简介](#1. Nginx 简介)
    • [1.1 什么是 Nginx](#1.1 什么是 Nginx)
    • [1.2 Nginx 的特点](#1.2 Nginx 的特点)
    • [1.3 Nginx 与 Apache 的对比](#1.3 Nginx 与 Apache 的对比)
    • [1.4 Nginx 主要应用场景](#1.4 Nginx 主要应用场景)
  • [2. 安装与初始化配置](#2. 安装与初始化配置)
    • [2.1 安装方式选择](#2.1 安装方式选择)
      • [2.1.1 官方源安装(推荐)](#2.1.1 官方源安装(推荐))
      • [2.1.2 源码编译安装](#2.1.2 源码编译安装)
    • [2.2 目录结构](#2.2 目录结构)
    • [2.3 防火墙配置](#2.3 防火墙配置)
    • [2.4 基本操作命令](#2.4 基本操作命令)
  • [3. 核心配置文件详解](#3. 核心配置文件详解)
    • [3.1 配置文件结构](#3.1 配置文件结构)
    • [3.2 全局配置 (main)](#3.2 全局配置 (main))
    • [3.3 事件配置 (events)](#3.3 事件配置 (events))
    • [3.4 HTTP 配置 (http)](#3.4 HTTP 配置 (http))
    • [3.5 配置文件常用指令说明](#3.5 配置文件常用指令说明)
  • [4. 虚拟主机配置实践](#4. 虚拟主机配置实践)
    • [4.1 基于域名的虚拟主机](#4.1 基于域名的虚拟主机)
      • [4.1.1 创建目录结构](#4.1.1 创建目录结构)
      • [4.1.2 配置虚拟主机](#4.1.2 配置虚拟主机)
      • [4.1.3 测试配置](#4.1.3 测试配置)
    • [4.2 基于端口的虚拟主机](#4.2 基于端口的虚拟主机)
    • [4.3 基于 IP 的虚拟主机](#4.3 基于 IP 的虚拟主机)
    • [4.4 默认虚拟主机](#4.4 默认虚拟主机)
  • [5. 反向代理配置](#5. 反向代理配置)
    • [5.1 基本反向代理配置](#5.1 基本反向代理配置)
    • [5.2 代理特定路径](#5.2 代理特定路径)
    • [5.3 代理 WebSocket](#5.3 代理 WebSocket)
    • [5.4 代理缓存配置](#5.4 代理缓存配置)
  • [6. 负载均衡配置](#6. 负载均衡配置)
    • [6.1 基本负载均衡配置](#6.1 基本负载均衡配置)
    • [6.2 负载均衡算法](#6.2 负载均衡算法)
    • [6.3 健康检查与故障转移](#6.3 健康检查与故障转移)
  • [7. SSL/TLS 配置与 HTTPS 部署](#7. SSL/TLS 配置与 HTTPS 部署)
    • [7.1 安装 SSL 证书](#7.1 安装 SSL 证书)
      • [7.1.1 使用 Let's Encrypt 获取免费证书](#7.1.1 使用 Let's Encrypt 获取免费证书)
      • [7.1.2 创建自签名证书(测试用)](#7.1.2 创建自签名证书(测试用))
    • [7.2 配置 HTTPS](#7.2 配置 HTTPS)
    • [7.3 SSL 配置说明](#7.3 SSL 配置说明)
  • [8. 常用模块配置](#8. 常用模块配置)
    • [8.1 状态监控模块 (stub\_status)](#8.1 状态监控模块 (stub_status))
    • [8.2 Gzip 压缩模块](#8.2 Gzip 压缩模块)
    • [8.3 防盗链配置](#8.3 防盗链配置)
    • [8.4 URL 重写 (rewrite)](#8.4 URL 重写 (rewrite))
  • [9. 性能优化实践](#9. 性能优化实践)
    • [9.1 工作进程优化](#9.1 工作进程优化)
    • [9.2 事件处理优化](#9.2 事件处理优化)
    • [9.3 连接优化](#9.3 连接优化)
    • [9.4 缓存优化](#9.4 缓存优化)
    • [9.5 静态资源优化](#9.5 静态资源优化)
  • [10. 日志管理与分析](#10. 日志管理与分析)
    • [10.1 日志配置](#10.1 日志配置)
    • [10.2 日志轮转配置](#10.2 日志轮转配置)
    • [10.3 日志分析工具](#10.3 日志分析工具)
      • [10.3.1 awstats](#10.3.1 awstats)
      • [10.3.2 goaccess](#10.3.2 goaccess)
  • [11. 日常运维与监控](#11. 日常运维与监控)
    • [11.1 常用运维命令](#11.1 常用运维命令)
    • [11.2 监控 Nginx 服务](#11.2 监控 Nginx 服务)
      • [11.2.1 使用 systemd 监控](#11.2.1 使用 systemd 监控)
      • [11.2.2 使用监控脚本](#11.2.2 使用监控脚本)
      • [11.2.3 使用专业监控工具](#11.2.3 使用专业监控工具)
  • [12. 安全加固措施](#12. 安全加固措施)
    • [12.1 隐藏 Nginx 版本信息](#12.1 隐藏 Nginx 版本信息)
    • [12.2 限制请求方法](#12.2 限制请求方法)
    • [12.3 限制请求速率](#12.3 限制请求速率)
    • [12.4 限制并发连接数](#12.4 限制并发连接数)
    • [12.5 防止 SQL 注入和 XSS 攻击](#12.5 防止 SQL 注入和 XSS 攻击)
    • [12.6 更改默认用户](#12.6 更改默认用户)
  • [13. 常见问题排查](#13. 常见问题排查)
    • [13.1 配置文件错误](#13.1 配置文件错误)
    • [13.2 端口被占用](#13.2 端口被占用)
    • [13.3 403 Forbidden 错误](#13.3 403 Forbidden 错误)
    • [13.4 502 Bad Gateway 错误](#13.4 502 Bad Gateway 错误)
    • [13.5 504 Gateway Timeout 错误](#13.5 504 Gateway Timeout 错误)
  • [14. 实战案例](#14. 实战案例)
    • [14.1 静态网站部署](#14.1 静态网站部署)
    • [14.2 Node.js 应用反向代理](#14.2 Node.js 应用反向代理)
    • [14.3 PHP 应用(如 WordPress)配置](#14.3 PHP 应用(如 WordPress)配置)
    • [14.4 负载均衡配置(Web 集群)](#14.4 负载均衡配置(Web 集群))

1. Nginx 简介

1.1 什么是 Nginx

Nginx(发音为 "engine x")是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。由俄罗斯程序员 Igor Sysoev 开发,第一个公开版本发布于 2004 年。

1.2 Nginx 的特点

  • 高性能:采用异步非阻塞事件驱动模型,能高效处理大量并发连接

  • 高可靠性:设计简洁稳定,故障率低

  • 高扩展性:模块化结构,支持多种第三方模块

  • 低资源消耗:相比 Apache 等服务器,相同硬件配置下能支持更多并发连接

  • 功能丰富:支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议,以及反向代理、负载均衡、URL 重写等功能

1.3 Nginx 与 Apache 的对比

特性 Nginx Apache
并发处理模型 异步非阻塞 多进程 / 多线程
内存占用 较高
静态资源处理 高效 一般
模块机制 静态编译 动态加载
配置风格 简洁 相对复杂
重写规则 强大 强大
适合场景 高并发、静态资源、反向代理 动态内容、模块丰富

Nginx 的模块机制:静态编译

编译阶段 与核心代码一起编译成可执行文件,运行时无法动态添加或移除模块。

  1. 工作原理

    • 编译时集成 :所有需要使用的模块(包括官方模块和第三方模块)必须在编译 Nginx 源码时通过 --with-模块名--add-module=模块路径 显式指定,编译后模块与 Nginx 核心绑定为单一可执行文件。

    • 运行时不可变:一旦编译完成,运行过程中无法新增、删除或替换模块,如需修改模块,必须重新编译并替换可执行文件。

  2. 优缺点

    • 优点:

      • 性能优异:模块与核心紧密集成,减少了动态加载的开销(如磁盘 I/O、内存分配),适合高并发场景。

      • 稳定性高:编译时会检查模块兼容性,避免运行时因模块冲突导致的崩溃。

      • 资源占用低:无需为动态加载预留额外内存或接口。

    • 缺点:

      • 灵活性差:修改模块必须重新编译,无法在线升级或调整功能。

      • 部署成本高:不同业务场景可能需要维护多个不同模块组合的 Nginx 版本。

Apache 的模块机制:动态加载

Apache 采用 动态共享对象(DSO,Dynamic Shared Object) 机制,模块以独立的动态链接库(.so 文件)形式存在,可在运行时动态加载或卸载,无需重新编译服务器核心。

  1. 工作原理

    • 模块独立编译 :模块单独编译为 .so 文件(如 mod_rewrite.somod_ssl.so),与 Apache 核心分离。
    • 配置文件控制加载 :通过配置文件(httpd.confconf.modules.d/ 目录下的文件)中的 LoadModule 指令指定需要加载的模块,修改后只需重启或重载 Apache 即可生效。
  2. 优缺点

    • 优点:
      • 灵活性高:无需重新编译即可添加 / 移除模块,便于按需扩展功能。
      • 维护成本低:一个 Apache 实例可通过配置加载不同模块,适应多种场景。
      • 升级方便:模块可单独升级,无需替换整个服务器核心。
    • 缺点:
      • 性能开销:动态加载会增加一定的内存占用和运行时开销(如符号解析、内存映射)。
      • 兼容性风险:不同版本模块可能存在冲突,需严格匹配 Apache 核心版本。

1.4 Nginx 主要应用场景

  • 静态资源服务器(HTML、CSS、JavaScript、图片等)

  • 反向代理服务器

  • 负载均衡器

  • HTTP 缓存服务器

  • API 网关

  • 动静分离部署

  • SSL 终端代理

2. 安装与初始化配置

2.1 安装方式选择

CentOS 7 上安装 Nginx 主要有两种方式:官方源安装和源码编译安装。

2.1.1 官方源安装(推荐)

官方源提供了最新稳定版的 Nginx,安装和更新都非常方便:

bash 复制代码
# 安装官方源
cat > /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

# 安装 nginx
yum install -y nginx

# 启动并设置开机自启
systemctl start nginx
systemctl enable nginx

# 验证安装
nginx -v  # 显示版本信息
systemctl status nginx  # 检查服务状态

2.1.2 源码编译安装

当需要特定模块或自定义编译选项时,可选择源码编译安装:

bash 复制代码
# 安装依赖包
yum install -y gcc gcc-c++ make zlib-devel pcre-devel openssl-devel wget

# 创建系统用户
useradd -M -s /sbin/nologin nginx

# 下载源码包(请从官网获取最新稳定版地址)
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# 配置编译选项
./configure \
  --prefix=/usr/local/nginx \
  --user=nginx \
  --group=nginx \
  --with-http_ssl_module \
  --with-http_stub_status_module \
  --with-http_realip_module \
  --with-pcre \
  --with-stream \
  --with-http_gzip_static_module

# 编译安装
make && make install

# 创建 systemd 服务文件
cat > /usr/lib/systemd/system/nginx.service << 'EOF'
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

# 启动服务
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx

2.2 目录结构

官方源安装的 Nginx 主要目录结构:

bash 复制代码
/etc/nginx/                 # 配置文件主目录
├── nginx.conf              # 主配置文件
├── conf.d/                 # 子配置文件目录
├── default.d/              # 默认服务器配置
├── koi-utf
├── koi-win
├── mime.types              # MIME类型定义
├── scgi_params             # SCGI参数
├── uwsgi_params            # uWSGI参数
└── win-utf
/usr/share/nginx/html/      # 默认网站根目录
/var/log/nginx/             # 日志目录
/var/cache/nginx/           # 缓存目录
/usr/sbin/nginx             # 可执行程序

2.3 防火墙配置

bash 复制代码
# 开放 HTTP (80) 和 HTTPS (443) 端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload

# 查看开放的端口
firewall-cmd --zone=public --list-ports

2.4 基本操作命令

bash 复制代码
# 检查配置文件语法
nginx -t

# 启动 Nginx
systemctl start nginx

# 停止 Nginx
systemctl stop nginx

# 重启 Nginx
systemctl restart nginx

# 平滑重启(不中断服务)
systemctl reload nginx
# 或
nginx -s reload

# 查看 Nginx 状态
systemctl status nginx

# 设置开机自启
systemctl enable nginx

# 禁止开机自启
systemctl disable nginx

3. 核心配置文件详解

Nginx 的主配置文件是 /etc/nginx/nginx.conf(官方源安装)或 /usr/local/nginx/conf/nginx.conf(源码安装)。

3.1 配置文件结构

Nginx 配置文件采用块级结构,主要包含以下几个层级:

bash 复制代码
main                # 全局配置
├── events          # 事件处理配置
├── http            # HTTP 协议配置
│   ├── upstream    # 上游服务器配置(用于反向代理和负载均衡)
│   ├── server      # 虚拟主机配置
│   │   ├── location # URL 匹配配置
│   │   └── ...
│   └── ...
├── stream          # TCP/UDP 代理配置(可选)
└── ...

3.2 全局配置 (main)

全局配置部分设置 Nginx 服务器的基本运行参数:

nginx 复制代码
# 用户和组
user nginx;

# 工作进程数,建议设置为 CPU 核心数
worker_processes auto;

# 错误日志路径和级别(debug, info, notice, warn, error, crit)
error_log /var/log/nginx/error.log warn;

# PID 文件路径
pid /var/run/nginx.pid;

3.3 事件配置 (events)

事件配置部分设置 Nginx 处理连接的方式:

nginx 复制代码
events {
    # 每个工作进程的最大连接数
    worker_connections 1024;
    
    # 事件模型,Linux 推荐使用 epoll
    use epoll;
    
    # 是否允许同时接收多个网络连接
    multi_accept on;
}

3.4 HTTP 配置 (http)

HTTP 配置部分是 Nginx 最核心的配置,包含了所有与 HTTP 协议相关的设置:

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;
    
    # 启用 sendfile 系统调用,加速文件传输
    sendfile on;
    
    # 启用 tcp_nopush,在 sendfile 开启时有效
    tcp_nopush on;
    
    # 启用 tcp_nodelay,在 keepalive 连接时有效
    tcp_nodelay on;
    
    # 长连接超时时间
    keepalive_timeout 65;
    
    # 启用 gzip 压缩
    gzip on;
    
    # 引入其他配置文件
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

3.5 配置文件常用指令说明

指令 作用 示例
worker_processes 设置工作进程数量 worker_processes 4;worker_processes auto;
worker_connections 每个工作进程的最大连接数 worker_connections 1024;
use 指定事件处理模型 use epoll;
log_format 定义日志格式 见上文示例
access_log 设置访问日志 access_log /var/log/nginx/access.log main;
error_log 设置错误日志 error_log /var/log/nginx/error.log warn;
sendfile 启用 sendfile 系统调用 sendfile on;
keepalive_timeout 设置长连接超时时间 keepalive_timeout 65;
gzip 启用 gzip 压缩 gzip on;
include 引入其他配置文件 include /etc/nginx/conf.d/*.conf;

4. 虚拟主机配置实践

虚拟主机(Virtual Host)允许在同一台服务器上托管多个网站,Nginx 支持基于域名、IP 和端口的虚拟主机。

4.1 基于域名的虚拟主机

这是最常用的虚拟主机配置方式,通过不同的域名区分不同的网站。

4.1.1 创建目录结构

bash 复制代码
# 创建网站根目录
mkdir -p /var/www/{example.com,test.com}/{html,logs}

# 设置权限
chown -R nginx:nginx /var/www/
chmod -R 755 /var/www/

# 创建测试页面
echo "Welcome to example.com" > /var/www/example.com/html/index.html
echo "Welcome to test.com" > /var/www/test.com/html/index.html

4.1.2 配置虚拟主机

创建 example.com 的配置文件:

bash 复制代码
cat > /etc/nginx/sites-available/example.com.conf << 'EOF'
server {
    listen 80;
    server_name example.com www.example.com;
    
    root /var/www/example.com/html;
    index index.html index.htm;
    
    access_log /var/www/example.com/logs/access.log main;
    error_log /var/www/example.com/logs/error.log warn;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

创建 test.com 的配置文件:

复制代码
cat > /etc/nginx/sites-available/test.com.conf << 'EOF'
server {
    listen 80;
    server_name test.com www.test.com;
    
    root /var/www/test.com/html;
    index index.html index.htm;
    
    access_log /var/www/test.com/logs/access.log main;
    error_log /var/www/test.com/logs/error.log warn;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

启用虚拟主机配置:

bash 复制代码
# 创建软链接到 sites-enabled 目录
ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/test.com.conf /etc/nginx/sites-enabled/

# 检查配置并重启
nginx -t
systemctl reload nginx

4.1.3 测试配置

在本地 hosts 文件中添加域名解析(或在 DNS 服务器中配置):

ini 复制代码
192.168.1.100 example.com www.example.com
192.168.1.100 test.com www.test.com

然后通过浏览器访问这两个域名,应该能看到不同的页面内容。

4.2 基于端口的虚拟主机

通过不同的端口区分不同的网站:

bash 复制代码
cat > /etc/nginx/sites-available/example-8080.conf << 'EOF'
server {
    listen 8080;
    server_name example.com;
    
    root /var/www/example-8080/html;
    index index.html index.htm;
    
    access_log /var/www/example-8080/logs/access.log main;
    error_log /var/www/example-8080/logs/error.log warn;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

开放 8080 端口:

bash 复制代码
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload

启用配置:

bash 复制代码
ln -s /etc/nginx/sites-available/example-8080.conf /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

4.3 基于 IP 的虚拟主机

如果服务器有多个 IP 地址,可以基于 IP 地址配置虚拟主机:

nginx 复制代码
server {
    listen 192.168.1.100:80;
    # 无需设置 server_name 或设置为 _
    server_name _;
    
    root /var/www/ip1/html;
    # 其他配置...
}

server {
    listen 192.168.1.101:80;
    server_name _;
    
    root /var/www/ip2/html;
    # 其他配置...
}

4.4 默认虚拟主机

默认虚拟主机是指当请求的域名没有匹配到任何虚拟主机时,Nginx 会使用的虚拟主机配置:

nginx 复制代码
cat > /etc/nginx/sites-available/default.conf << 'EOF'
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    
    server_name _;
    
    root /var/www/default/html;
    index index.html;
    
    # 返回 403 禁止访问未知域名
    # location / {
    #     return 403;
    # }
    
    # 或者重定向到一个默认域名
    # return 301 http://example.com$request_uri;
}
EOF

5. 反向代理配置

反向代理是 Nginx 最常用的功能之一,它可以将客户端请求转发到后端服务器,并将后端服务器的响应返回给客户端。

5.1 基本反向代理配置

nginx 复制代码
server {
    listen 80;
    server_name proxy.example.com;
    
    # 反向代理配置
    location / {
        proxy_pass http://127.0.0.1:8080;  # 后端服务器地址
        proxy_set_header Host $host;       # 传递主机名
        proxy_set_header X-Real-IP $remote_addr;  # 传递真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

5.2 代理特定路径

只代理特定路径,其他路径由 Nginx 直接处理:

nginx 复制代码
server {
    listen 80;
    server_name example.com;
    
    root /var/www/example.com/html;
    index index.html;
    
    # 只代理 /api 路径
    location /api {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # 其他路径由 Nginx 直接处理
    location / {
        try_files $uri $uri/ =404;
    }
}

5.3 代理 WebSocket

WebSocket 协议需要特殊配置以支持长连接:

nginx 复制代码
location /ws {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

5.4 代理缓存配置

启用代理缓存可以减轻后端服务器压力,提高响应速度:

nginx 复制代码
# 在 http 块中定义缓存
http {
    # ... 其他配置 ...
    
    proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=proxy_cache:10m max_size=10g 
                     inactive=60m use_temp_path=off;
                     
    server {
        # ... 服务器配置 ...
        
        location / {
            proxy_pass http://backend_server;
            
            # 启用缓存
            proxy_cache proxy_cache;
            proxy_cache_valid 200 304 10m;  # 200和304响应缓存10分钟
            proxy_cache_valid any 1m;       # 其他响应缓存1分钟
            proxy_cache_key "$scheme$request_method$host$request_uri";
            
            # 缓存控制
            add_header X-Proxy-Cache $upstream_cache_status;
        }
    }
}

6. 负载均衡配置

Nginx 可以作为负载均衡器,将请求分发到多个后端服务器,提高系统的可用性和处理能力。

6.1 基本负载均衡配置

nginx 复制代码
http {
    # 定义上游服务器组
    upstream backend_servers {
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }
    
    server {
        listen 80;
        server_name lb.example.com;
        
        location / {
            proxy_pass http://backend_servers;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

6.2 负载均衡算法

Nginx 支持多种负载均衡算法,默认是轮询(round robin):

  1. 轮询(Round Robin):默认算法,请求按顺序分发到每个服务器

    nginx 复制代码
    upstream backend_servers {
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }
  2. 权重(Weight):根据权重分配请求,权重越高,分配的请求越多

    nginx 复制代码
    upstream backend_servers {
        server 192.168.1.101:80 weight=3;  # 30% 的请求
        server 192.168.1.102:80 weight=3;  # 30% 的请求
        server 192.168.1.103:80 weight=4;  # 40% 的请求
    }
  3. IP 哈希(IP Hash):根据客户端 IP 地址的哈希结果分配请求,确保同一客户端始终访问同一服务器

    nginx 复制代码
    upstream backend_servers {
        ip_hash;
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }
  4. 最少连接(Least Connections):将请求分配到当前连接数最少的服务器

    nginx 复制代码
    upstream backend_servers {
        least_conn;
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }

6.3 健康检查与故障转移

配置服务器健康检查和自动故障转移:

nginx 复制代码
upstream backend_servers {
    server 192.168.1.101:80 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:80 max_fails=3 fail_timeout=30s;
    server 192.168.1.103:80 backup;  # 备用服务器,只有主服务器都不可用时才启用
}
  • max_fails:允许请求失败的次数,默认 1

  • fail_timeout:失败后暂停多长时间不再请求该服务器,默认 10 秒

  • backup:标记为备用服务器

7. SSL/TLS 配置与 HTTPS 部署

7.1 安装 SSL 证书

可以通过 Let's Encrypt 获取免费证书,或使用自签名证书进行测试。

7.1.1 使用 Let's Encrypt 获取免费证书

bash 复制代码
# 安装 Certbot
yum install -y epel-release
yum install -y certbot python2-certbot-nginx

# 获取并自动配置证书
certbot --nginx -d example.com -d www.example.com

7.1.2 创建自签名证书(测试用)

bash 复制代码
# 创建证书目录
mkdir -p /etc/nginx/ssl

# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/example.com.key \
  -out /etc/nginx/ssl/example.com.crt

7.2 配置 HTTPS

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

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL 证书配置
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    # SSL 优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/example.com.crt;
    
    # 网站根目录和索引文件
    root /var/www/example.com/html;
    index index.html;
    
    # 其他配置...
    location / {
        try_files $uri $uri/ =404;
    }
}

7.3 SSL 配置说明

配置项 作用
ssl_protocols 指定支持的 TLS 协议版本
ssl_ciphers 指定加密套件,优先选择安全性高的套件
ssl_prefer_server_ciphers 优先使用服务器端的加密套件
ssl_session_cache 启用 SSL 会话缓存,提高性能
ssl_session_timeout SSL 会话超时时间
ssl_stapling 启用 OCSP stapling,提高 TLS 握手性能
ssl_stapling_verify 验证 OCSP 响应

8. 常用模块配置

8.1 状态监控模块 (stub_status)

nginx 复制代码
server {
    # ... 其他配置 ...
    
    location /nginx_status {
        stub_status on;
        access_log off;
        # 限制访问来源
        allow 192.168.1.0/24;
        allow 127.0.0.1;
        deny all;
    }
}

访问 /nginx_status 可以看到类似以下的输出:

nginx 复制代码
Active connections: 2 
server accepts handled requests
 100 100 300 
Reading: 0 Writing: 1 Waiting: 1 
  • Active connections:当前活跃的连接数

  • accepts:总接受的连接数

  • handled:总处理的连接数

  • requests:总请求数

  • Reading:正在读取客户端请求的连接数

  • Writing:正在向客户端发送响应的连接数

  • Waiting:处于空闲状态的连接数

8.2 Gzip 压缩模块

nginx 复制代码
http {
    # ... 其他配置 ...
    
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;  # 压缩级别,1-9,级别越高压缩率越高但消耗CPU越多
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

8.3 防盗链配置

nginx 复制代码
server {
    # ... 其他配置 ...
    
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        # 允许自己的域名和百度、谷歌等搜索引擎访问
        valid_referers none blocked example.com *.example.com *.baidu.com *.google.com;
        
        # 如果不是允许的来源,则返回403或指定图片
        if ($invalid_referer) {
            return 403;
            # 或者返回一张防盗链图片
            # rewrite ^/ https://example.com/anti-leech.jpg last;
        }
    }
}

8.4 URL 重写 (rewrite)

nginx 复制代码
server {
    # ... 其他配置 ...
    
    # 将不带 www 的域名重定向到带 www 的域名
    if ($host = 'example.com') {
        return 301 https://www.example.com$request_uri;
    }
    
    # 将 .html 后缀的 URL 重写为无后缀
    rewrite ^/(.*)\.html$ /$1 permanent;
    
    # 伪静态配置示例(适合 PHP 框架)
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

9. 性能优化实践

9.1 工作进程优化

nginx 复制代码
# 设置为 CPU 核心数
worker_processes auto;

# 绑定工作进程到特定 CPU 核心(提高缓存利用率)
worker_cpu_affinity 0001 0010 0100 1000;  # 4 核心 CPU 示例

# 每个工作进程的最大打开文件数
worker_rlimit_nofile 65535;

9.2 事件处理优化

nginx 复制代码
events {
    worker_connections 10240;  # 提高每个工作进程的最大连接数
    use epoll;                 # 使用 epoll 事件模型
    multi_accept on;           # 允许同时接受多个连接
}

9.3 连接优化

nginx 复制代码
http {
    # ... 其他配置 ...
    
    # 启用长连接
    keepalive_timeout 65;
    keepalive_requests 100;    # 长连接上允许的最大请求数
    
    # TCP 优化
    tcp_nopush on;             # 发送数据时先缓存,直到缓存满或超时
    tcp_nodelay on;            # 禁用 Nagle 算法,减少延迟
    
    # 客户端请求头读取超时
    client_header_timeout 15;
    # 客户端请求体读取超时
    client_body_timeout 15;
    # 发送响应超时
    send_timeout 15;
}

9.4 缓存优化

nginx 复制代码
http {
    # ... 其他配置 ...
    
    # 开启文件缓存
    open_file_cache max=10000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # 启用 gzip 压缩
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 1k;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

9.5 静态资源优化

nginx 复制代码
server {
    # ... 其他配置 ...
    
    # 静态资源缓存设置
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;          # 设置 30 天缓存
        add_header Cache-Control "public, max-age=2592000";
        access_log off;       # 不记录静态资源访问日志
    }
    
    # 大型静态文件优化
    location ~* \.(zip|rar|7z|tar|gz|bz2)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
        tcp_nopush on;
        sendfile on;
    }
}

10. 日志管理与分析

10.1 日志配置

nginx 复制代码
http {
    # 定义主日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    '$request_time $upstream_response_time';
    
    # 定义访问日志
    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;
    
    # 虚拟主机日志配置
    server {
        server_name example.com;
        access_log /var/log/nginx/example.com.access.log main;
        error_log /var/log/nginx/example.com.error.log error;
        # ... 其他配置 ...
    }
}

10.2 日志轮转配置

创建日志轮转配置文件:

bash 复制代码
cat > /etc/logrotate.d/nginx << 'EOF'
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 nginx adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}
EOF

配置说明:

  • daily:每天轮转一次

  • missingok:忽略缺失的日志文件

  • rotate 14:保留 14 天的日志

  • compress:压缩轮转后的日志

  • delaycompress:延迟压缩,不压缩最近一次轮转的日志

  • notifempty:如果日志为空则不轮转

  • create 0640 nginx adm:创建新日志文件的权限和所有者

  • postrotate:轮转后执行的命令,通知 Nginx 重新打开日志文件

10.3 日志分析工具

10.3.1 awstats

bash 复制代码
# 安装 awstats
yum install -y awstats

# 配置 awstats
cp /etc/awstats/awstats.model.conf /etc/awstats/awstats.example.com.conf

# 编辑配置文件,修改以下内容
# SiteDomain="example.com"
# LogFile="/var/log/nginx/example.com.access.log"
# LogFormat=1

# 生成统计报告
awstats_updateall.pl now

# 设置定时任务
echo "0 0 * * * /usr/share/awstats/wwwroot/cgi-bin/awstats_updateall.pl now" >> /etc/crontab

10.3.2 goaccess

bash 复制代码
# 安装 goaccess
yum install -y goaccess

# 实时分析日志
goaccess /var/log/nginx/access.log -c

# 生成 HTML 报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED

11. 日常运维与监控

11.1 常用运维命令

bash 复制代码
# 检查配置文件
nginx -t

# 平滑重启
nginx -s reload

# 查看 Nginx 版本和编译参数
nginx -V

# 查看 Nginx 进程
ps aux | grep nginx

# 查看 Nginx 占用的端口
netstat -tlnp | grep nginx
# 或
ss -tlnp | grep nginx

# 查看连接数统计
netstat -an | grep :80 | wc -l

11.2 监控 Nginx 服务

11.2.1 使用 systemd 监控

bash 复制代码
systemctl status nginx

11.2.2 使用监控脚本

创建一个简单的监控脚本:

bash 复制代码
cat > /usr/local/bin/nginx_monitor.sh << 'EOF'
#!/bin/bash

NGINX_PID=$(cat /var/run/nginx.pid)

if [ -z "$NGINX_PID" ]; then
    echo "Nginx is not running, starting it..."
    systemctl start nginx
    exit 1
fi

if ! ps -p $NGINX_PID > /dev/null; then
    echo "Nginx process $NGINX_PID not found, restarting..."
    systemctl restart nginx
    exit 1
fi

echo "Nginx is running normally (PID: $NGINX_PID)"
exit 0
EOF

# 赋予执行权限
chmod +x /usr/local/bin/nginx_monitor.sh

添加到定时任务:

bash 复制代码
echo "*/5 * * * * /usr/local/bin/nginx_monitor.sh >> /var/log/nginx/monitor.log 2>&1" >> /etc/crontab

11.2.3 使用专业监控工具

  • Zabbix:可以通过 Zabbix Agent 监控 Nginx 状态

  • Prometheus + Grafana:配合 nginx-exporter 监控 Nginx 性能指标

    安装 nginx-exporter:

    bash 复制代码
    # 下载并安装
    wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
    tar zxvf nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
    cp nginx-prometheus-exporter /usr/local/bin/
    
    # 创建 systemd 服务
    cat > /etc/systemd/system/nginx-exporter.service << 'EOF'
    [Unit]
    Description=Nginx Prometheus Exporter
    After=network.target
    
    [Service]
    User=nginx
    Group=nginx
    ExecStart=/usr/local/bin/nginx-prometheus-exporter -nginx.scrape-uri=http://localhost/nginx_status
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    # 启动服务
    systemctl start nginx-exporter
    systemctl enable nginx-exporter

12. 安全加固措施

12.1 隐藏 Nginx 版本信息

nginx 复制代码
http {
    # 隐藏版本信息
    server_tokens off;
    # ... 其他配置 ...
}

12.2 限制请求方法

nginx 复制代码
server {
    # ... 其他配置 ...
    
    # 只允许 GET, HEAD, POST 请求方法
    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 405;
    }
}

12.3 限制请求速率

nginx 复制代码
http {
    # 定义限流规则
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
    
    server {
        # ... 其他配置 ...
        
        # 应用限流规则
        location / {
            limit_req zone=req_limit burst=20 nodelay;
            # ... 其他配置 ...
        }
    }
}
  • rate=10r/s:限制每秒 10 个请求

  • burst=20:允许 20 个请求的突发流量

  • nodelay:不延迟处理突发请求

12.4 限制并发连接数

nginx 复制代码
http {
    # 定义连接限制规则
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    server {
        # ... 其他配置 ...
        
        # 应用连接限制
        location / {
            limit_conn conn_limit 10;  # 每个 IP 最多 10 个并发连接
            # ... 其他配置 ...
        }
    }
}

12.5 防止 SQL 注入和 XSS 攻击

nginx 复制代码
server {
    # ... 其他配置 ...
    
    # 过滤常见的 SQL 注入字符
    if ($request_uri ~* "union.*select.*\(") {
        return 403;
    }
    if ($request_uri ~* "union.*all.*select.*") {
        return 403;
    }
    if ($request_uri ~* "concat.*\(") {
        return 403;
    }
    
    # 添加安全响应头
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Content-Security-Policy "default-src 'self'" always;
}

12.6 更改默认用户

bash 复制代码
# 创建新用户
useradd -M -s /sbin/nologin nginx_user

# 修改 Nginx 配置
sed -i 's/^user nginx;/user nginx_user;/' /etc/nginx/nginx.conf

# 更改文件权限
chown -R nginx_user:nginx_user /var/www/
chown -R nginx_user:nginx_user /var/log/nginx/
chown -R nginx_user:nginx_user /var/cache/nginx/

# 重启 Nginx
systemctl restart nginx

13. 常见问题排查

13.1 配置文件错误

bash 复制代码
# 检查配置文件语法
nginx -t

# 查看错误日志
tail -f /var/log/nginx/error.log

常见配置错误:

  • 缺少分号 ;

  • 括号不匹配

  • 指令拼写错误

  • 端口被占用

13.2 端口被占用

bash 复制代码
# 查看端口占用情况
netstat -tlnp | grep 80
# 或
ss -tlnp | grep 80

# 终止占用端口的进程
kill -9 <进程ID>

13.3 403 Forbidden 错误

可能原因及解决方法:

  1. 文件权限问题:确保 Nginx 用户有访问文件的权限

    bash 复制代码
    chown -R nginx:nginx /var/www/
    chmod -R 755 /var/www/
  2. SELinux 限制:临时关闭 SELinux 测试

    bash 复制代码
    setenforce 0

    如果问题解决,可永久设置 SELinux 规则:

    bash 复制代码
    chcon -R -t httpd_sys_content_t /var/www/
  3. 目录索引问题:确保目录有索引文件或配置了 autoindex

    bash 复制代码
    location / {
        index index.html index.htm;
        # 或启用目录浏览
        # autoindex on;
    }

13.4 502 Bad Gateway 错误

通常是后端服务器问题:

  1. 检查后端服务器是否运行,例如php-fpm.service

    bash 复制代码
    systemctl status php-fpm.service
  2. 检查后端服务器是否监听正确的端口

    bash 复制代码
    netstat -tlnp | grep <后端端口>
  3. 检查防火墙是否允许 Nginx 访问后端服务器

    bash 复制代码
    firewall-cmd --zone=public --add-port=<后端端口>/tcp --permanent
    firewall-cmd --reload
  4. 查看 Nginx 错误日志获取更多信息

    bash 复制代码
    tail -f /var/log/nginx/error.log

13.5 504 Gateway Timeout 错误

后端服务器响应超时:

nginx 复制代码
location / {
    proxy_pass http://backend_server;
    proxy_connect_timeout 60s;    # 连接超时时间
    proxy_send_timeout 60s;       # 发送超时时间
    proxy_read_timeout 60s;       # 读取超时时间
}

14. 实战案例

14.1 静态网站部署

nginx 复制代码
server {
    listen 80;
    listen 443 ssl http2;
    server_name static.example.com;
    
    # SSL 配置
    ssl_certificate /etc/nginx/ssl/static.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/static.example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    
    # 网站根目录
    root /var/www/static.example.com;
    index index.html index.htm;
    
    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
        access_log off;
    }
    
    # 启用 gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/javascript text/xml application/xml application/xml+rss text/javascript;
    
    # 日志配置
    access_log /var/log/nginx/static.example.com.access.log main;
    error_log /var/log/nginx/static.example.com.error.log warn;
}

14.2 Node.js 应用反向代理

nginx 复制代码
server {
    listen 80;
    server_name node.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name node.example.com;
    
    ssl_certificate /etc/nginx/ssl/node.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/node.example.com.key;
    # 其他 SSL 配置...
    
    # 反向代理到 Node.js 应用
    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;
        
        # WebSocket 支持
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 120s;
    }
    
    # 静态资源由 Nginx 直接处理
    location /static {
        alias /var/www/node.example.com/static;
        expires 1d;
        add_header Cache-Control "public, max-age=86400";
    }
}

14.3 PHP 应用(如 WordPress)配置

nginx 复制代码
server {
    listen 80;
    server_name wordpress.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name wordpress.example.com;
    
    ssl_certificate /etc/nginx/ssl/wordpress.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/wordpress.example.com.key;
    # 其他 SSL 配置...
    
    root /var/www/wordpress.example.com;
    index index.php index.html;
    
    # PHP 处理
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass 127.0.0.1:9000;  # PHP-FPM 监听地址
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        
        # 超时设置
        fastcgi_connect_timeout 30s;
        fastcgi_send_timeout 30s;
        fastcgi_read_timeout 60s;
    }
    
    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
        access_log off;
    }
    
    # WordPress 固定链接支持
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

14.4 负载均衡配置(Web 集群)

nginx 复制代码
http {
    # 上游服务器配置
    upstream web_servers {
        ip_hash;  # 确保会话一致性
        server 192.168.1.101:80 weight=3 max_fails=3 fail_timeout=30s;
        server 192.168.1.102:80 weight=3 max_fails=3 fail_timeout=30s;
        server 192.168.1.103:80 weight=2 max_fails=3 fail_timeout=30s;
        server 192.168.1.104:80 backup;  # 备用服务器
    }
    
    # 负载均衡器配置
    server {
        listen 80;
        listen 443 ssl http2;
        server_name cluster.example.com;
        
        ssl_certificate /etc/nginx/ssl/cluster.example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/cluster.example.com.key;
        # 其他 SSL 配置...
        
        # 代理到上游服务器
        location / {
            proxy_pass http://web_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;
            proxy_set_header X-Forwarded-Proto $scheme;
            
            # 代理缓存配置
            proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=web_cache:100m max_size=10g inactive=60m;
            proxy_cache web_cache;
            proxy_cache_valid 200 304 10m;
            proxy_cache_valid any 1m;
        }
        
        # 静态资源缓存
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            proxy_pass http://web_servers;
            proxy_set_header Host $host;
            expires 30d;
            add_header Cache-Control "public, max-age=2592000";
            proxy_cache web_cache;
            proxy_cache_valid 200 304 30d;
        }
    }
}
相关推荐
程序猿阿伟2 小时前
《OpenClaw端口通信失效全解:监听修改与防火墙规则落地指南》
服务器·数据库·windows
虾..2 小时前
Linux 五种IO模型
linux·服务器·数据库
L1624762 小时前
Nginx 高可用集群与 LVS 负载均衡实战指南(场景选型对比 + 完整配置步骤 + 主备漂移部署实操)
nginx·负载均衡·lvs
CDN3602 小时前
中小团队安全方案:360CDN 高防服务器基础配置
运维·服务器·安全
Coolmuster_cn2 小时前
如何删除三星手机和平板电脑上的应用程序
服务器·智能手机
筱顾大牛2 小时前
黑马点评---用户签到、UV统计
android·服务器·uv
kcuwu.2 小时前
Python文件操作零基础及进阶
android·服务器·python
光影少年2 小时前
跨域问题如何解决?
前端·nginx·前端框架
**蓝桉**2 小时前
Keepalived+Nginx+Tomcat 高可用负载均衡(续)
nginx·tomcat·负载均衡