Nginx
一、Nginx 基础
1. Nginx 是什么?
Nginx 是一个高性能的 Web 服务器和反向代理服务器。
核心特性:
- ✅ 高性能 - 高并发、低内存占用
- ✅ 反向代理 - 负载均衡、请求转发
- ✅ 静态文件服务 - 高效提供静态资源
- ✅ SSL/TLS 终止 - HTTPS 支持
- ✅ 模块化 - 丰富的功能模块
2. Nginx vs Apache
| 特性 | Nginx | Apache |
|---|---|---|
| 并发模型 | 事件驱动 | 多进程/多线程 |
| 内存占用 | 低 | 较高 |
| 静态文件 | 性能优秀 | 性能良好 |
| 动态内容 | 需要反向代理 | 原生支持 |
| 配置 | 相对简单 | 功能丰富但复杂 |
| 适用场景 | 高并发、反向代理 | 传统 Web 应用 |
3. Nginx 应用场景
- ✅ Web 服务器 - 提供静态文件
- ✅ 反向代理 - 转发请求到后端服务
- ✅ 负载均衡 - 分发请求到多个服务器
- ✅ API 网关 - 统一入口
- ✅ SSL 终止 - HTTPS 处理
二、文件结构
- Linux: /etc/nginx/nginx.conf 或 /usr/local/nginx/conf/nginx.conf
- Windows: nginx/conf/nginx.conf
二、基本配置
# 全局块
user nginx; # 工作进程的用户
worker_processes auto; # 工作进程数(通常设为CPU核心数)
error_log /var/log/nginx/error.log; # 错误日志
pid /var/run/nginx.pid; # PID 文件路径
# events 块:影响 Nginx 与客户端的连接方式
events {
worker_connections 1024; # 每个进程最大连接数
use epoll; # Linux 下推荐使用 epoll 提升性能
}
# http 块:核心配置,包含大多数 Web 服务配置
http {
include /etc/nginx/mime.types; # 支持的 MIME 类型
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; # 高效传输文件
tcp_nopush on; # 提升网络效率
keepalive_timeout 65; # 长连接超时时间
gzip on; # 开启 Gzip 压缩
# server 块:虚拟主机配置(可有多个)
server {
listen 80; # 监听端口
server_name localhost; # 域名
# location 块:匹配请求路径
location / {
root /usr/share/nginx/html; # 静态文件根目录
index index.html index.htm; # 默认首页
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}三、常用功能配置示例
1、静态资源服务器
server {
listen 80;
server_name static.example.com;
location / {
root /var/www/static;
index index.html;
expires 1y; # 缓存1年
add_header Cache-Control "public, immutable";
}
# 图片、JS、CSS 缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public";
}
}2. 反向代理(Reverse Proxy)
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:5000; # 转发到本地5000端口
proxy_http_version 1.1;
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;
}
}3. 负载均衡(Load Balancing)
upstream backend {
# 轮询(默认)
server 192.168.1.10:5000;
server 192.168.1.11:5000;
# 权重
# server 192.168.1.10:5000 weight=3;
# server 192.168.1.11:5000 weight=1;
# IP 哈希(会话保持)
# ip_hash;
# 最少连接
# least_conn;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
}
}4. HTTPS / SSL 配置
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
location / {
root /var/www/html;
index index.html;
}
}
# HTTP 强制跳转 HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}5. 跨域配置
location /api/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://localhost:5000;
}6. 常用命令
# 启动 Nginx
nginx
# 停止
nginx -s stop # 快速停止
nginx -s quit # 优雅关闭
# 重新加载配置(热更新)
nginx -s reload
# 重启
systemctl restart nginx
# 测试配置文件语法
nginx -t
# 查看版本
nginx -v7. 访问控制
基于 IP 的访问控制(allow / deny)
- 语法
allow address | CIDR | all;
deny address | CIDR | all;- 示例 1:只允许内网访问管理后台
location /admin/ {
# 只允许 192.168.1.0/24 网段访问
allow 192.168.1.0/24;
# 允许本地访问
allow 127.0.0.1;
# 拒绝所有其他 IP
deny all;
root /var/www/html;
index index.html;
}- 示例 2:禁止某个 IP 访问
location / {
# 禁止恶意 IP
deny 192.168.1.100;
deny 203.0.113.50;
# 允许其他所有
allow all;
proxy_pass http://backend;
}- 注意
- llow 和 deny 的顺序很重要,Nginx 会按顺序匹配,第一个匹配的规则生效。
- 通常把 deny all 放在最后。
- 支持 IPv4 和 IPv6。
基于 Referer 的访问控制(防盗链)
防止其他网站直接引用你的静态资源(如图片、JS、CSS)。
示例:只允许本站和百度搜索访问图片
location ~* \.(jpg|jpeg|png|gif|ico)$ {
# 有效的来源
valid_referers none blocked server_names
*.baidu.com *.google.com;
# 如果 referer 不在白名单,返回 403 或替换图片
if ($invalid_referer) {
# 方法1:返回403
# return 403;
# 方法2:返回默认图片(更友好)
rewrite ^/.*$ /images/forbidden.jpg last;
}
expires 1y;
add_header Cache-Control "public";
}- valid_referers:定义合法的来源。
- $invalid_referer:变量,为 1 表示 referer 无效。
四、性能优化
1. 工作进程优化
nginx
# 工作进程数(通常设为 CPU 核心数)
worker_processes auto;
# 每个进程最大连接数
events {
worker_connections 1024;
use epoll; # Linux 下使用 epoll
}2. 缓存优化
nginx
# 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
server {
location / {
proxy_cache my_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_pass http://backend;
}
}3. Gzip 压缩
nginx
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;4. 连接优化
nginx
keepalive_timeout 65;
keepalive_requests 100;
tcp_nopush on;
tcp_nodelay on;五、安全配置
1. 隐藏 Nginx 版本
nginx
server_tokens off;2. 限制请求大小
nginx
client_max_body_size 10m;
client_body_buffer_size 128k;3. 防止 DDoS
nginx
# 限制连接数
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_conn conn_limit_per_ip 10;
# 限制请求速率
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
limit_req zone=req_limit_per_ip burst=20 nodelay;4. 安全头
nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;六、日志管理
1. 访问日志
nginx
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log detailed;2. 错误日志
nginx
error_log /var/log/nginx/error.log warn;3. 日志轮转
bash
# 使用 logrotate
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}七、常见面试题
Q1: Nginx 如何处理高并发?
- 事件驱动模型 - 使用 epoll(Linux)处理大量连接
- 多进程架构 - 主进程 + 多个工作进程
- 非阻塞 I/O - 异步处理请求
- 内存池 - 减少内存分配开销
Q2: Nginx 负载均衡算法?
- 轮询(Round Robin) - 默认,依次分配
- 权重(Weight) - 按权重分配
- IP 哈希(ip_hash) - 同一 IP 总是路由到同一服务器
- 最少连接(least_conn) - 分配到连接数最少的服务器
- fair - 按响应时间分配(需要第三方模块)
Q3: Nginx 反向代理和正向代理的区别?
反向代理:
- 代理服务器端
- 客户端不知道真实服务器
- 用于负载均衡、隐藏服务器
正向代理:
- 代理客户端
- 服务器不知道真实客户端
- 用于翻墙、缓存
Q4: 如何实现 Nginx 高可用?
- Keepalived - 实现虚拟 IP 漂移
- 多实例部署 - 多个 Nginx 实例
- 健康检查 - 监控后端服务状态
- 自动故障转移 - 主节点故障时切换到备用节点
Q5: Nginx 如何实现灰度发布?
nginx
upstream backend {
server 192.168.1.10:5000 weight=90; # 90% 流量
server 192.168.1.11:5000 weight=10; # 10% 流量(新版本)
}八、最佳实践
- ✅ 合理配置工作进程 - 通常设为 CPU 核心数
- ✅ 启用 Gzip 压缩 - 减少传输大小
- ✅ 使用缓存 - 提升性能
- ✅ 配置日志 - 便于排查问题
- ✅ 安全配置 - 隐藏版本、限制请求
- ✅ 监控 - 监控连接数、请求速率
- ✅ 定期更新 - 保持最新版本
- ✅ 测试配置 - 修改后先测试
- ❌ 不要忽略错误日志 - 及时发现问题
- ❌ 不要过度优化 - 根据实际需求配置