Nginx 全栈实操

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

1. 源码编译

核心步骤
bash 复制代码
# 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 状态。

完整代码 & 步骤
bash 复制代码
# /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;
        }
    }
}
bash 复制代码
# 验证效果(用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 脚本 + 定时任务)
bash 复制代码
# /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
bash 复制代码
# 加执行权限+定时任务(每天0点执行)
chmod +x /root/nginx_log_cut.sh
echo "0 0 * * * /root/nginx_log_cut.sh" >> /var/spool/cron/root
crontab -l  # 验证定时任务
步骤 2:ELK 对接日志
bash 复制代码
# 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-*响应头,允许指定域名跨域访问。

完整代码 & 步骤
bash 复制代码
# /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.100 MASTER
Nginx 备节点 172.25.254.101 BACKUP
VIP 172.25.254.200 对外访问 IP
步骤 1:安装 Keepalived(两台节点都执行)
bash 复制代码
dnf install keepalived -y
步骤 2:主节点 Keepalived 配置
bash 复制代码
# /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 配置
bash 复制代码
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:启动 & 验证
bash 复制代码
# 两台节点启动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:准备目录结构
bash 复制代码
mkdir -p /docker/nginx/{conf,conf.d,html,logs}
步骤 2:编写 Nginx 配置文件
bash 复制代码
# /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;
}
bash 复制代码
# /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 容器
bash 复制代码
# 拉取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
验证效果
bash 复制代码
# 访问测试
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
相关推荐
️️(^~^)2 小时前
HAPORXY实验环境
linux·运维·服务器
不像程序员的程序媛2 小时前
阿里云负载均衡器知多少?
运维·服务器·负载均衡
_OP_CHEN2 小时前
【Linux系统编程】(四十)线程控制终极指南:从资源共享到实战操控,带你吃透线程全生命周期
linux·运维·操作系统·线程·进程·c/c++·线程控制
Fantasy丶夜雨笙歌2 小时前
Web 服务基石 Nginx
运维·前端·nginx
赋创小助手2 小时前
服务器主板为何不再采用ATX?以超微X14DBM-AP 为例解析
运维·服务器·人工智能·深度学习·自然语言处理·硬件架构
芝士雪豹只抽瑞克五2 小时前
HAProxy 七层负载均衡器笔记
运维·笔记·负载均衡
欧云服务器2 小时前
宝塔邮局磁盘满了怎么清理?linux磁盘清理教程
运维·服务器
觅特科技-互站2 小时前
告别手动微调Prompt:DevOps用陌讯Skills重构AI运维工作流
运维·prompt·线性回归·kmeans·devops
天空属于哈夫克32 小时前
基于 Webhook 的企业微信外部群自动化推送集成
运维·自动化·企业微信