一、Nginx 基础:源码编译 + 服务管理

1. 源码编译

核心步骤
# 1. 装依赖(少一个编译会跪)
dnf install gcc openssl-devel pcre2-devel zlib-devel -y
# 2. 编译配置(记核心参数,其余按需加)
./configure \
--prefix=/usr/local/nginx \  # 安装根路径(固定好记)
--user=nginx --group=nginx \  # 普通用户运行,规避权限风险
--with-http_ssl_module \      # 必开:支持HTTPS
--with-stream \              # 必开:支持四层负载(TCP/UDP)
--with-http_stub_status_module  # 可选:监控Nginx状态
# 3. 编译+安装(make别加-j,容易崩掉)
make && make install
配套操作
  1. 创建专用用户:useradd -s /sbin/nologin -M nginx
  2. 环境变量:vim ~/.bash_profilePATH=/usr/local/nginx/sbin:$PATHsource生效;
  3. 系统服务:写nginx.service文件,实现systemctl管理(开机自启 / 重启)。

2. 平滑升级 / 回滚

  1. 升级逻辑:编译新版本→替换二进制文件→发信号kill -USR2 主进程ID,不中断服务;
  2. 回滚逻辑:备份新文件→替换回旧二进制→kill -HUP 主进程IDkill -WINCH 新进程ID回收;
  3. 核心考点:别用kill -9!面试问 “Nginx 升级不中断服务的原理”,就说 “信号控制进程替换”。

二、Nginx 核心配置:从基础到实用

1. 虚拟主机 & 路径匹配

location 匹配优先级(记死):=(精确)> ^~(前缀)> ~/~*(正则)> 无符号(模糊)

root vs alias(易混点):

  1. root:路径拼接(root /a + 访问/b/a/b
  2. alias:路径替换(alias /a + 访问/b/a

      2. 实用小功能

      功能核心配置 / 操作
      访问认证htpasswd -cmb .htpasswd 用户名 密码 + auth_basic + auth_basic_user_file
      自定义错误页error_page 404/502 /error.html,搭配 alias 指向自定义页面
      下载服务器autoindex on(列表)+ limit_rate 1024k(控速)+ autoindex_localtime on(时间优化)
      防盗链valid_referers + if ($invalid_referer),非法来源返回 404 / 跳转防盗链图片
      长连接优化配置keepalive_timeout(时长)+ keepalive_requests(次数),减少握手开销

      3. 反向代理 & 负载均衡

      七层代理(HTTP/HTTPS)
      • 基础配置:定义upstream集群,proxy_pass转发,weight调权重,backup设备用节点;
      • 进阶优化:
      1. 动静分离:.php/.jsp转发给后端(Tomcat/PHP-FPM),静态文件 Nginx 直接处理;
      2. 缓存加速:proxy_cache缓存动态页面,压测 QPS 直接翻倍;
      3. 透传信息:proxy_set_header X-Forwarded-For $remote_addr,让后端拿到真实客户端 IP。
      四层代理(TCP/UDP)

      核心:开启stream模块,可代理 MySQL(3306/TCP)、DNS(53/UDP);

      配置示例:

      stream {
        upstream mysql_server {
          server 172.25.254.10:3306 max_fails=3 fail_timeout=30s;
          server 172.25.254.20:3306 max_fails=3 fail_timeout=30s;
        }
        server {
          listen 172.25.254.100:3306;
          proxy_pass mysql_server;
        }
      }

      三、进阶拓展:Nginx + 生态整合

      实验 1:Nginx 防 DDOS 攻击(安全防护必做)

      实验目标

      限制单个 IP 的并发连接数和请求频率,抵御简单的 CC/DDOS 攻击,保护后端服务。

      核心原理

      利用limit_conn_zone(限制并发连接)+limit_req_zone(限制请求频率),结合共享内存记录 IP 状态。

      完整代码 & 步骤
      # /usr/local/nginx/conf/conf.d/anti_ddos.conf
      http {
          # 1. 定义连接数限制:共享内存conn_limit,key为IP,大小10M
          limit_conn_zone $remote_addr zone=conn_limit:10m;
          # 2. 定义请求频率限制:10r/s(每秒10次),桶容量20
          limit_req_zone $remote_addr zone=req_limit:10m rate=10r/s;
          server {
              listen 80;
              server_name anti-ddos.timinglee.org;
              location / {
                  root /usr/local/nginx/html;
                  # 限制单个IP最大并发连接数10
                  limit_conn conn_limit 10;
                  # 限制请求频率:burst=20(突发请求缓冲),nodelay(不延迟处理)
                  limit_req zone=req_limit burst=20 nodelay;
                  # 超过限制返回503
                  limit_req_status 503;
                  limit_conn_status 503;
              }
          }
      }

      # 验证效果(用ab压测)
      ab -n 1000 -c 50 http://anti-ddos.timinglee.org/
      # 效果:超过10并发/10r/s的请求返回503,后端服务不会被打垮!

      实验 2:Nginx 日志切割 + ELK 分析

      实验目标

      解决 Nginx 日志越积越大的问题,自动切割日志,并对接 ELK(Elasticsearch+Logstash+Kibana)分析日志。

      步骤 1:日志自动切割(用 shell 脚本 + 定时任务)
      # /root/nginx_log_cut.sh
      #!/bin/bash
      # 日志目录
      LOG_DIR="/usr/local/nginx/logs"
      # 昨天的日期
      YESTERDAY=$(date -d "yesterday" +%Y%m%d)
      # 切割access.log
      mv $LOG_DIR/access.log $LOG_DIR/access_$YESTERDAY.log
      # 向Nginx主进程发信号,重新生成日志文件
      kill -USR1 $(cat $LOG_DIR/nginx.pid)
      # 删除7天前的旧日志
      find $LOG_DIR -name "access_*.log" -mtime +7 -delete

      # 加执行权限+定时任务(每天0点执行)
      chmod +x /root/nginx_log_cut.sh
      echo "0 0 * * * /root/nginx_log_cut.sh" >> /var/spool/cron/root
      crontab -l  # 验证定时任务
      步骤 2:ELK 对接日志
      # Logstash配置文件 /etc/logstash/conf.d/nginx_log.conf
      input {
        file {
          path => "/usr/local/nginx/logs/access_*.log"
          start_position => "beginning"
          sincedb_path => "/dev/null"
        }
      }
      filter {
        grok {
          match => { "message" => "%{HTTPD_COMBINEDLOG}" }
        }
        date {
          match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
        }
      }
      output {
        elasticsearch {
          hosts => ["172.25.254.40:9200"]  # ES地址
          index => "nginx-access-%{+YYYY.MM.dd}"
        }
        stdout { codec => rubydebug }
      }
      验证效果

      启动 Logstash 后,Kibana 可可视化查看:访问 IP 分布、请求状态码、热门接口、响应时间等,快速定位异常请求。

      实验 3:Nginx 解决跨域问题

      实验目标

      前端访问不同域名的后端接口时,解决浏览器 “跨域限制” 问题。

      核心原理

      通过添加Access-Control-Allow-*响应头,允许指定域名跨域访问。

      完整代码 & 步骤
      # /usr/local/nginx/conf/conf.d/cors.conf
      server {
          listen 80;
          server_name api.timinglee.org;
          location /api {
              proxy_pass http://172.25.254.10:8080;  # 后端接口地址
              # 核心:跨域配置
              add_header Access-Control-Allow-Origin *;  # 允许所有域名(生产可指定具体域名)
              add_header Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS";  # 允许的请求方法
              add_header Access-Control-Allow-Headers "Content-Type,Authorization";  # 允许的请求头
              # 处理OPTIONS预检请求
              if ($request_method = OPTIONS) {
                  return 204;  # 预检请求直接返回204,不转发到后端
              }
          }
      }
      验证效果

      前端页面访问http://api.timinglee.org/api时,浏览器控制台不会再报 “CORS policy” 错误,正常请求数据。

      实验 4:Nginx + Keepalived 实现高可用

      实验目标

      搭建双 Nginx 节点的高可用集群,主节点宕机后备节点自动接管 VIP,避免 Nginx 单点故障。

      实验环境
      节点IP 地址角色
      Nginx 主节点172.25.254.100MASTER
      Nginx 备节点172.25.254.101BACKUP
      VIP172.25.254.200对外访问 IP
      步骤 1:安装 Keepalived(两台节点都执行)
      dnf install keepalived -y
      步骤 2:主节点 Keepalived 配置
      # /etc/keepalived/keepalived.conf
      global_defs {
         router_id NGINX_MASTER
      }
      # 监控Nginx状态:Nginx挂了就降低优先级
      vrrp_script check_nginx {
          script "/usr/bin/systemctl is-active nginx"
          interval 2
          weight -20
      }
      vrrp_instance VI_1 {
          state MASTER
          interface eth0  # 绑定VIP的网卡
          virtual_router_id 51
          priority 100  # 主节点优先级更高
          advert_int 1
          authentication {
              auth_type PASS
              auth_pass 1111
          }
          virtual_ipaddress {
              172.25.254.200/24  # VIP地址
          }
          track_script {
              check_nginx
          }
      }
      步骤 3:备节点 Keepalived 配置
      global_defs {
         router_id NGINX_BACKUP
      }
      vrrp_script check_nginx {
          script "/usr/bin/systemctl is-active nginx"
          interval 2
          weight -20
      }
      vrrp_instance VI_1 {
          state BACKUP
          interface eth0
          virtual_router_id 51
          priority 90  # 优先级低于主节点
          advert_int 1
          authentication {
              auth_type PASS
              auth_pass 1111
          }
          virtual_ipaddress {
              172.25.254.200/24
          }
          track_script {
              check_nginx
          }
      }
      步骤 4:启动 & 验证
      # 两台节点启动Keepalived
      systemctl enable --now keepalived
      # 验证1:主节点有VIP,备节点无
      ip a show eth0  # 主节点能看到172.25.254.200
      # 验证2:停掉主节点Nginx,VIP自动切到备节点
      systemctl stop nginx  # 主节点执行
      ip a show eth0  # 备节点能看到VIP

      实验 5:Docker+Nginx 容器化部署

      实验目标

      用 Docker 部署 Nginx,挂载配置 / 日志 / 静态文件目录,实现 “配置持久化、日志可查”。

      步骤 1:准备目录结构
      mkdir -p /docker/nginx/{conf,conf.d,html,logs}
      步骤 2:编写 Nginx 配置文件
      # /docker/nginx/conf/nginx.conf
      worker_processes auto;
      error_log /var/log/nginx/error.log warn;
      pid /var/run/nginx.pid;
      events {
          worker_connections 1024;
      }
      http {
          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 on;
          keepalive_timeout 65;
          include /etc/nginx/conf.d/*.conf;
      }
      # /docker/nginx/conf.d/default.conf
      server {
          listen 80;
          server_name localhost;
          root /usr/share/nginx/html;
          index index.html;
          location / {
              try_files $uri $uri/ =404;
          }
      }
      步骤 3:启动 Docker 容器
      # 拉取Nginx镜像
      docker pull nginx:1.28.1
      # 启动容器(挂载目录+端口映射)
      docker run -d \
        --name nginx-docker \
        -p 8080:80 \
        -v /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
        -v /docker/nginx/conf.d:/etc/nginx/conf.d \
        -v /docker/nginx/html:/usr/share/nginx/html \
        -v /docker/nginx/logs:/var/log/nginx \
        nginx:1.28.1
      验证效果
      # 访问测试
      curl http://172.25.254.100:8080
      # 修改静态文件(容器内无需重启Nginx)
      echo "Docker Nginx Test" > /docker/nginx/html/index.html
      curl http://172.25.254.100:8080  # 立即生效
      # 查看日志
      cat /docker/nginx/logs/access.log