第 2 章:Nginx 实战
学习目标
- 安装并启动 Nginx
- 配置静态网站和反向代理
- 配置 HTTPS 和负载均衡
- 避开常见配置坑
一、Nginx 安装与启动
bash
# Ubuntu / Debian
apt update && apt install nginx -y
# CentOS / Rocky
dnf install nginx -y
# macOS
brew install nginx
# 启动
nginx # 前台启动
nginx -s reload # 重载配置(平滑)
nginx -s stop # 优雅停止
nginx -t # 测配置语法主配置目录结构:
/etc/nginx/
├── nginx.conf # 主配置(通常 include 其他文件)
├── conf.d/ # 自定义 server(include 进主配置)
├── sites-available/ # 可用站点(Ubuntu 风格)
└── sites-enabled/ # 启用站点(软链到上面)⚠️ 坑 1:改完配置必须
nginx -t验证,再reload。直接reload可能把语法错误带进线上。
二、最小 HTTP 服务
nginx
# /etc/nginx/conf.d/hello.conf
server {
listen 80;
server_name hello.local;
root /var/www/hello;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}bash
nginx -t && nginx -s reload
curl http://hello.local # 看到 index.html 内容三、反向代理(关键)
把请求转发到后端应用:
nginx
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1: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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}⚠️ 坑 2:
proxy_pass末尾带不带/行为不同:
http://127.0.0.1:8080→ 原路径/api/user转发到后端/api/userhttp://127.0.0.1:8080/→ 转发的后端路径变成去掉 location 段后的/user⚠️ 坑 3:不加
proxy_set_header X-Real-IP,后端拿到的 IP 全是127.0.0.1,日志和限速全是错的。
四、负载均衡(upstream)
nginx
upstream backend {
# 负载策略:默认轮询(round-robin)
server 10.0.0.11:8080 weight=3; # 权重,3 倍流量
server 10.0.0.12:8080 weight=1;
server 10.0.0.13:8080;
# 备用 / 健康
server 10.0.0.99:8080 backup; # 其他全挂才启用
keepalive 32; # 长连接池(性能优化)
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}负载策略(写在 upstream 块):
| 指令 | 行为 |
|---|---|
round-robin(默认) | 平均轮询 |
least_conn; | 最少连接优先 |
ip_hash; | 同 IP 固定后端(会话保持) |
random; | 随机 |
⚠️ 坑 4:
ip_hash不能和权重混用效果一致,需要会话粘性才用它。Redis 共享 session 比ip_hash更靠谱。
五、HTTPS(Certbot 自动签发)
bash
# 安装 certbot
apt install certbot python3-certbot-nginx -y
# 自动签发 + 改配置
certbot --nginx -d example.com -d www.example.comcertbot 会自动往 server 里塞这一段:
nginx
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 安全头(可选)
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# 80 自动跳转 443
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}证书 90 天过期,加定时任务续签:
bash
0 3 * * * certbot renew --quiet --deploy-hook "nginx -s reload"⚠️ 坑 5:HSTS 一旦下发,浏览器会强制 HTTPS,测试环境别乱加,否则想换回 HTTP 复杂。
六、静态资源 + 缓存
nginx
server {
listen 80;
root /var/www/static;
location / {
try_files $uri =404;
}
# 静态资源长缓存
location ~* \.(js|css|png|jpg|webp|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# index.html 短缓存(避免新版本不生效)
location = /index.html {
expires 5m;
add_header Cache-Control "no-cache";
}
# 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1024;
}⚠️ 坑 6:CSS/JS 用文件名加 hash(
app.a3b4c5.js),immutable才安全。否则改文件后用户 30 天看不到新版本。
七、限流与黑名单
nginx
# 限流(每秒 10 个请求,突发 20)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}
# 黑名单
location /admin/ {
allow 10.0.0.0/8; # 内网段
deny all; # 其他全拒
}八、日志分析
bash
# 实时看
tail -f /var/log/nginx/access.log
# 统计 Top IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 找慢请求(>1s 的)
awk '$NF > 1 {print $0}' /var/log/nginx/access.log | head九、本章小结
| 功能 | 关键指令 |
|---|---|
| 反向代理 | proxy_pass + proxy_set_header X-Real-IP |
| 负载均衡 | upstream 块 + server |
| HTTPS | certbot --nginx 自动签 + 续 |
| 限流 | limit_req_zone + limit_req |
| 静态缓存 | expires + Cache-Control |
动手练习
- 配置静态网站 + gzip,验证
curl -I看到Content-Encoding: gzip - 反向代理 8080 上的 SpringBoot,验证后端日志拿到真实 IP
- 用
upstream配两台后端,curl 多请求几次看是否轮询 - 用 certbot 给自己的域名签证书,验证浏览器访问 HTTPS 成功
下一章:第 3 章:Docker 入门 →