#Nginx 实战教程
#什么是Nginx?
Nginx(发音为 "engine-x")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。它以其高稳定性、丰富的功能集、示例配置文件和低系统资源消耗而闻名。
#Nginx的主要特点:
- 高性能:使用异步事件驱动架构,处理大量并发连接
- 低内存消耗:相比传统Apache,内存占用更少
- 高稳定性:运行稳定,极少出现故障
- 热部署:可以在不停机的情况下升级
- 模块化设计:丰富的第三方模块生态
- 反向代理:强大的负载均衡和代理功能
#1. Nginx安装与配置
#1.1 Ubuntu/Debian系统安装
# 更新包列表
sudo apt update
# 安装Nginx
sudo apt install nginx
# 检查Nginx状态
sudo systemctl status nginx
# 启动Nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
# 检查Nginx版本
nginx -v#1.2 CentOS/RHEL系统安装
# 安装EPEL仓库
sudo yum install epel-release
# 安装Nginx
sudo yum install nginx
# 或使用dnf (CentOS 8+)
sudo dnf install nginx
# 启动和设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx#1.3 Docker方式安装
# 拉取Nginx镜像
docker pull nginx:latest
# 运行Nginx容器
docker run -d \
--name my-nginx \
-p 80:80 \
-p 443:443 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
-v $(pwd)/html:/usr/share/nginx/html \
nginx:latest
# 查看容器日志
docker logs my-nginx#1.4 Docker Compose方式安装
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: nginx-server
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf.d:/etc/nginx/conf.d:ro
- ./html:/usr/share/nginx/html:ro
- ./logs:/var/log/nginx
- ./ssl:/etc/nginx/ssl
networks:
- web-network
networks:
web-network:
driver: bridge#2. Nginx基础配置
#2.1 主配置文件结构
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
}#2.2 服务器块配置
# /etc/nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /usr/share/nginx/html;
index index.html index.htm index.php;
# 字符编码
charset utf-8;
# 访问日志
access_log /var/log/nginx/example.access.log main;
error_log /var/log/nginx/example.error.log;
# 主要位置配置
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}#3. 反向代理配置
#3.1 基本反向代理
# 反向代理到后端应用服务器
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000; # Node.js应用
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 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓冲设置
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}#3.2 负载均衡配置
# 定义上游服务器组
upstream backend_app {
# 轮询(默认)
server 192.168.1.10:3000 weight=3;
server 192.168.1.11:3000 weight=2;
server 192.168.1.12:3000 weight=1;
# 最少连接
# least_conn;
# IP哈希
# ip_hash;
# 响应时间加权
# fair; # 需要安装fair模块
# 健康检查
keepalive 32;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend_app;
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.3 高级负载均衡策略
# 使用least_conn策略
upstream backend_least_conn {
least_conn;
server app1.example.com:8080 max_fails=3 fail_timeout=30s;
server app2.example.com:8080 max_fails=3 fail_timeout=30s;
server app3.example.com:8080 max_fails=3 fail_timeout=30s;
}
# 使用IP哈希策略
upstream backend_ip_hash {
ip_hash;
server app1.example.com:8080;
server app2.example.com:8080;
server app3.example.com:8080;
}
# 使用权重策略
upstream backend_weight {
server app1.example.com:8080 weight=5;
server app2.example.com:8080 weight=3;
server app3.example.com:8080 weight=1;
}#4. SSL/TLS配置
#4.1 Let's Encrypt SSL证书配置
# 安装Certbot
sudo apt install certbot python3-certbot-nginx
# 获取SSL证书
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期
sudo crontab -e
# 添加以下行
0 12 * * * /usr/bin/certbot renew --quiet#4.2 SSL配置示例
server {
listen 80;
server_name example.com www.example.com;
# 重定向HTTP到HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS安全头部
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}#4.3 自定义SSL配置
# 高安全性SSL配置
server {
listen 443 ssl http2;
server_name secure.example.com;
# 证书配置
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_trusted_certificate /path/to/ca-chain.crt;
# SSL协议和加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
# OCSP装订
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# 会话管理
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# 安全头部
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;" always;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}#5. 缓存配置
#5.1 静态资源缓存
# 静态资源缓存配置
server {
listen 80;
server_name static.example.com;
root /var/www/static;
# 图片、视频、音频文件
location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|mp4|webm|ogg|mp3|wav)$ {
expires 1M;
add_header Cache-Control "public, immutable";
access_log off;
log_not_found off;
}
# CSS、JS文件
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 字体文件
location ~* \.(woff|woff2|ttf|eot|otf)$ {
expires 1y;
add_header Access-Control-Allow-Origin *;
}
# 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
}#5.2 代理缓存
# 定义缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
listen 80;
server_name cached.example.com;
location / {
# 启用缓存
proxy_cache my_cache;
# 缓存键
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
# 缓存时间
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
# 缓存绕过条件
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_pragma;
# 传递原始头部
proxy_pass http://backend_server;
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;
# 缓存相关头部
add_header X-Cache-Status $upstream_cache_status;
add_header X-Cache-Key $upstream_cache_key;
}
# 缓存清除接口
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge my_cache "$scheme$request_method$host$1$is_args$args";
}
}#6. 安全配置
#6.1 基本安全配置
# 安全相关的头部设置
server {
listen 80;
server_name secure.example.com;
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# XSS防护
add_header X-XSS-Protection "1; mode=block" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Referrer策略
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Feature策略
add_header Feature-Policy "geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'self'; vibrate 'none'; fullscreen 'self'; payment 'none'; usb 'none';" always;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
# 隐藏Nginx版本
server_tokens off;
}#6.2 访问控制
# IP白名单
server {
listen 80;
server_name admin.example.com;
# 限制访问IP
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}
# 基本身份认证
server {
listen 80;
server_name protected.example.com;
location / {
# 启用基本认证
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}
# 限制请求频率
server {
listen 80;
server_name api.example.com;
# 定义限制区域
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;
location /api/ {
# 应用请求限制
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend_api;
}
location /login {
# 登录限制更严格
limit_req zone=login burst=5 nodelay;
proxy_pass http://auth_service;
}
}#7. 高级配置
#7.1 负载均衡高级配置
# 使用keepalive连接池
upstream backend_with_keepalive {
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
# 保持连接
keepalive 32;
keepalive_requests 100;
keepalive_timeout 60s;
}
# 健康检查配置
upstream backend_with_health_check {
server backend1.example.com:8080 max_fails=3 fail_timeout=30s;
server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
server backend3.example.com:8080 max_fails=3 fail_timeout=30s;
# 服务权重
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
listen 80;
server_name loadbalanced.example.com;
location / {
proxy_pass http://backend_with_keepalive;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 超时配置
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
# 重试配置
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
}#7.2 WebSocket支持
# WebSocket代理配置
server {
listen 80;
server_name ws.example.com;
location /websocket {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 86400;
proxy_send_timeout 86400;
proxy_connect_timeout 86400;
}
}
upstream websocket_backend {
server ws1.example.com:8080;
server ws2.example.com:8080;
}#7.3 Gzip压缩优化
# 高级Gzip配置
server {
listen 80;
server_name compressed.example.com;
# Gzip配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
# 压缩类型
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json
application/atom+xml
application/rss+xml
application/xhtml+xml
application/x-javascript
application/x-httpd-php
application/x-font-ttf
application/x-font-opentype
application/vnd.ms-fontobject
font/ttf
font/opentype
font/otf
image/svg+xml;
# 禁用IE6压缩
gzip_disable "MSIE [1-6]\.";
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}#8. 监控与日志
#8.1 日志配置
# 详细的日志配置
http {
# 自定义日志格式
log_format detailed_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
# JSON格式日志
log_format json_log escape=json '{'
'"@timestamp": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"request": "$request", '
'"status": $status, '
'"body_bytes_sent": $body_bytes_sent, '
'"request_time": $request_time, '
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent", '
'"upstream_addr": "$upstream_addr", '
'"upstream_status": "$upstream_status", '
'"upstream_response_time": "$upstream_response_time"'
'}';
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/access.log detailed_log;
error_log /var/log/nginx/error.log warn;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}
}#8.2 监控端点
# Nginx状态监控
server {
listen 80;
server_name status.example.com;
# Nginx状态页面
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.0.0/16;
deny all;
}
# 限制访问
location / {
return 404;
}
}#8.3 性能监控
#!/bin/bash
# nginx_monitor.sh - Nginx性能监控脚本
# 检查Nginx进程
if pgrep nginx > /dev/null; then
echo "Nginx is running"
else
echo "Nginx is not running"
exit 1
fi
# 检查Nginx配置
if nginx -t; then
echo "Nginx configuration is valid"
else
echo "Nginx configuration has errors"
exit 1
fi
# 获取连接数
CONNECTIONS=$(ss -tlnp | grep nginx | wc -l)
echo "Active Nginx connections: $CONNECTIONS"
# 获取请求统计
if curl -s http://localhost/nginx_status > /dev/null; then
REQUESTS=$(curl -s http://localhost/nginx_status | awk 'NR==3{print $1}')
echo "Total requests: $REQUESTS"
fi
# 检查错误日志
ERROR_COUNT=$(grep -c "$(date '+%Y/%m/%d')" /var/log/nginx/error.log)
echo "Errors today: $ERROR_COUNT"#9. 最佳实践
#9.1 性能优化配置
# 性能优化配置
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
accept_mutex off;
}
http {
# 基本性能设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
keepalive_requests 100;
# 连接池
lingering_close off;
reset_timedout_connection on;
# 缓冲设置
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;
# 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# 日志优化
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
}#9.2 安全加固配置
# 安全加固配置
http {
# 隐藏版本号
server_tokens off;
# 安全头部
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 Referrer-Policy "strict-origin-when-cross-origin" always;
# 限制请求大小
client_max_body_size 10M;
# 限制请求长度
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
# 防止恶意请求
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$ ) {
return 405;
}
# 防止HTTP走私
underscores_in_headers on;
# 限制访问频率
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
server {
listen 80;
server_name _;
# 应用通用限制
limit_req zone=general burst=20 nodelay;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
}
}
}#9.3 部署最佳实践
#!/bin/bash
# nginx_deployment.sh - Nginx部署脚本
# 配置备份
BACKUP_DIR="/etc/nginx/backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
echo "Backing up current configuration..."
cp -r /etc/nginx/nginx.conf $BACKUP_DIR/nginx.conf_$DATE
cp -r /etc/nginx/conf.d $BACKUP_DIR/conf.d_$DATE
# 验证配置
echo "Testing configuration..."
if nginx -t; then
echo "Configuration test passed"
# 平滑重启
echo "Restarting Nginx..."
nginx -s reload
# 验证服务状态
sleep 2
if pgrep nginx > /dev/null; then
echo "Nginx restarted successfully"
# 清理旧备份(保留最近5个)
ls -t $BACKUP_DIR | tail -n +6 | xargs -I {} rm -rf $BACKUP_DIR/{}
else
echo "Nginx restart failed, restoring backup..."
cp $BACKUP_DIR/nginx.conf_$DATE /etc/nginx/nginx.conf
nginx -s reload
exit 1
fi
else
echo "Configuration test failed, restoring backup..."
cp $BACKUP_DIR/nginx.conf_$DATE /etc/nginx/nginx.conf
exit 1
fi
echo "Deployment completed successfully"#9.4 应用场景配置示例
# API网关配置示例
upstream api_gateway {
server api1.example.com:8080 weight=3;
server api2.example.com:8080 weight=2;
server api3.example.com:8080 weight=1;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL配置
ssl_certificate /etc/ssl/certs/api.example.com.crt;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
# 限流配置
limit_req_zone $binary_remote_addr zone=api_rate:10m rate=100r/s;
location / {
limit_req zone=api_rate burst=200 nodelay;
proxy_pass http://api_gateway;
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;
# API特定头部
add_header X-API-Version "1.0";
add_header X-RateLimit-Limit "100";
add_header X-RateLimit-Remaining "99";
}
}
# 静态文件服务器配置示例
server {
listen 80;
server_name static.example.com;
root /var/www/static;
# 静态资源优化
location ~* \.(jpg|jpeg|png|gif|ico|svg|css|js|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
gzip_static on;
}
# 安全配置
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location / {
try_files $uri $uri/ =404;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
}#总结
Nginx是一个功能强大、高性能的Web服务器和反向代理服务器。通过合理的配置,可以实现负载均衡、SSL终止、缓存、安全防护等功能。掌握Nginx的核心概念和配置技巧,能够帮助开发者构建高性能、高可用的Web应用架构。在实际部署中,需要注意安全配置、性能优化和监控维护,确保系统的稳定运行。

