1. Nginx 简介#
Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。以其高性能、稳定性、丰富的功能集、简单的配置文件和低系统资源消耗而闻名。
1.1 主要特性#
- 高并发处理能力
- 低内存消耗
- 高可靠性
- 热部署
- 负载均衡
- 反向代理
- 静态文件服务
- SSL/TLS支持
2. 安装 Nginx#
2.1 Ubuntu/Debian 系统#
1
2
3
4
5
6
7
8
9
10
11
| # 更新包列表
sudo apt update
# 安装nginx
sudo apt install nginx
# 启动nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
|
2.2 CentOS/RHEL 系统#
1
2
3
4
5
6
7
8
9
10
11
| # 安装EPEL仓库
sudo yum install epel-release
# 安装nginx
sudo yum install nginx
# 启动nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
|
2.3 macOS 系统#
1
2
3
4
5
| # 使用Homebrew安装
brew install nginx
# 启动nginx
brew services start nginx
|
2.4 编译安装#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 下载源码
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置编译选项
./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_gzip_static_module
# 编译安装
make && sudo make install
|
3. Nginx 目录结构#
3.1 主要目录#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| /etc/nginx/ # 主配置目录
├── nginx.conf # 主配置文件
├── conf.d/ # 额外配置文件目录
├── sites-available/ # 可用站点配置
├── sites-enabled/ # 启用站点配置
├── snippets/ # 配置片段
└── modules-enabled/ # 启用的模块
/var/log/nginx/ # 日志目录
├── access.log # 访问日志
└── error.log # 错误日志
/var/www/html/ # 默认网站根目录
/usr/share/nginx/html/ # 默认页面目录
|
4. 基础配置#
4.1 主配置文件结构#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| # /etc/nginx/nginx.conf
# 全局块
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# events块
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
# http块
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;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
|
4.2 虚拟主机配置#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| # /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
# 访问日志
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# 静态文件处理
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 安全设置
location ~ /\. {
deny all;
}
}
|
5. 反向代理配置#
5.1 基本反向代理#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
|
5.2 负载均衡#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| # 定义上游服务器组
upstream backend {
# 轮询(默认)
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
# 权重负载均衡
# server 192.168.1.10:8080 weight=3;
# server 192.168.1.11:8080 weight=2;
# server 192.168.1.12:8080 weight=1;
# IP哈希
# ip_hash;
# 最少连接
# least_conn;
# 健康检查
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
|
6. SSL/HTTPS 配置#
6.1 SSL 证书配置#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL证书配置
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-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;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# HTTP重定向到HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
|
6.2 Let’s Encrypt 免费证书#
1
2
3
4
5
6
7
8
9
10
| # 安装certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期
sudo crontab -e
# 添加以下行
0 12 * * * /usr/bin/certbot renew --quiet
|
7. 性能优化#
7.1 工作进程优化#
1
2
3
4
5
6
7
8
9
10
11
12
| # 设置工作进程数(通常等于CPU核心数)
worker_processes auto;
# 绑定工作进程到CPU核心
worker_cpu_affinity auto;
# 工作进程连接数
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
|
7.2 缓存配置#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| http {
# 文件缓存
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_pass http://backend;
}
}
}
|
7.3 压缩优化#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Brotli压缩(需要安装模块)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/json application/javascript text/xml application/xml;
|
8. 安全配置#
8.1 基础安全设置#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| # 隐藏Nginx版本
server_tokens off;
# 限制请求大小
client_max_body_size 10M;
# 限制请求速率
http {
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
# 登录接口限流
location /login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://backend;
}
# API接口限流
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}
}
|
8.2 防止恶意访问#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| # 阻止特定User-Agent
if ($http_user_agent ~* (bot|crawler|spider)) {
return 403;
}
# 阻止特定IP
deny 192.168.1.100;
allow 192.168.1.0/24;
deny all;
# 防止SQL注入和XSS
if ($args ~* "(union|select|insert|delete|update|drop|script|alert)") {
return 403;
}
# 防止目录遍历
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 防止访问敏感文件
location ~* \.(htaccess|htpasswd|ini|log|sh|sql|conf)$ {
deny all;
}
|
9. 日志管理#
9.1 自定义日志格式#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| http {
# 详细日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$pipe $upstream_cache_status';
# JSON格式日志
log_format json escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":$request_time'
'}';
access_log /var/log/nginx/access.log detailed;
}
|
9.2 日志轮转#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx adm
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
|
10. 常用命令#
10.1 服务管理#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 启动nginx
sudo systemctl start nginx
# 停止nginx
sudo systemctl stop nginx
# 重启nginx
sudo systemctl restart nginx
# 重新加载配置
sudo systemctl reload nginx
# 查看状态
sudo systemctl status nginx
# 测试配置文件
sudo nginx -t
# 查看配置文件路径
nginx -T
# 查看版本信息
nginx -v
nginx -V
|
10.2 信号控制#
1
2
3
4
5
6
7
8
| # 优雅停止
sudo nginx -s quit
# 快速停止
sudo nginx -s stop
# 重新加载配置
sudo nginx -s reload
# 重新打开日志文件
sudo nginx -s reopen
|
11. 故障排查#
11.1 常见错误及解决方案#
11.1.1 403 Forbidden#
1
2
3
4
5
6
7
8
9
| # 检查文件权限
ls -la /var/www/html/
# 修改权限
sudo chown -R nginx:nginx /var/www/html/
sudo chmod -R 755 /var/www/html/
# 检查SELinux(CentOS/RHEL)
sudo setsebool -P httpd_can_network_connect 1
|
11.1.2 502 Bad Gateway#
1
2
3
4
5
6
7
8
9
| # 检查后端服务是否运行
netstat -tlnp | grep :3000
# 检查防火墙
sudo ufw status
sudo firewall-cmd --list-all
# 检查nginx错误日志
sudo tail -f /var/log/nginx/error.log
|
11.1.3 504 Gateway Timeout#
1
2
3
4
5
6
7
| # 增加超时时间
location / {
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_pass http://backend;
}
|
11.2 性能监控#
1
2
3
4
5
6
7
8
9
10
11
| # 查看连接状态
ss -tuln | grep :80
# 监控nginx进程
top -p $(pgrep nginx)
# 查看访问统计
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 分析响应时间
awk '{print $NF}' /var/log/nginx/access.log | sort -n | tail -10
|
12. 高级配置#
12.1 动态模块加载#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 加载模块
load_module modules/ngx_http_geoip_module.so;
http {
# 使用GeoIP
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
CN yes;
US yes;
}
server {
if ($allowed_country = no) {
return 403;
}
}
}
|
12.2 Lua脚本集成#
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 需要安装lua模块
location /api {
access_by_lua_block {
local headers = ngx.req.get_headers()
if not headers["authorization"] then
ngx.status = 401
ngx.say("Unauthorized")
ngx.exit(401)
end
}
proxy_pass http://backend;
}
|
12.3 实时配置更新#
1
2
3
4
5
6
7
8
9
10
| # 使用nginx-plus的API
location /api {
api write=on;
allow 127.0.0.1;
deny all;
}
# 动态添加上游服务器
# curl -X POST -d '{"server":"192.168.1.100:8080"}' \
# http://localhost/api/6/http/upstreams/backend/servers
|
13. 最佳实践#
13.1 配置文件组织#
1
2
3
4
5
6
7
8
9
10
| /etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/
│ ├── gzip.conf # 压缩配置
│ ├── security.conf # 安全配置
│ └── ssl.conf # SSL配置
├── sites-available/
│ ├── example.com # 站点配置
│ └── api.example.com # API配置
└── sites-enabled/ # 启用的站点(软链接)
|
13.2 配置模板#
1
2
3
4
5
6
7
8
9
10
| # /etc/nginx/conf.d/security.conf
# 安全头配置
add_header X-Frame-Options DENY 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;
# 隐藏服务器信息
server_tokens off;
more_clear_headers Server;
|
13.3 监控和告警#
1
2
3
4
5
6
7
8
9
10
11
12
| #!/bin/bash
# nginx_monitor.sh
# 检查nginx状态
if ! systemctl is-active --quiet nginx; then
echo "Nginx is down!" | mail -s "Nginx Alert" admin@example.com
fi
# 检查错误日志
error_count=$(tail -100 /var/log/nginx/error.log | grep "$(date '+%Y/%m/%d')" | wc -l)
if [ $error_count -gt 10 ]; then
echo "High error rate: $error_count errors today" | mail -s "Nginx Error Alert" admin@example.com
fi
|