为什么棒球教练穿队服?
2026/1/18 16:09:21
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; # TCP优化 tcp_nodelay on; # 禁用Nagle算法 keepalive_timeout 65; # 长连接超时 client_max_body_size 20m; # 最大上传文件大小 # Gzip压缩 gzip on; gzip_comp_level 6; gzip_types text/plain text/css application/json; # 上游服务器(负载均衡) upstream backend { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080; server 192.168.1.102:8080 backup; # 负载均衡策略:轮询(默认)、ip_hash、least_conn } }本篇博文由我来详细解读上面这个Nginx HTTP配置块:
include /etc/nginx/mime.types; # 包含MIME类型定义文件 default_type application/octet-stream; # 默认MIME类型.html→text/html.css→text/css.jpg→image/jpeglog_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';日志字段解析:
| 变量 | 含义 | 示例 |
|---|---|---|
$remote_addr | 客户端IP | 192.168.1.100 |
$remote_user | 认证用户名 | -(未认证) |
$time_local | 访问时间 | [18/Jan/2023:10:12:33 +0800] |
$request | 请求行 | "GET /index.html HTTP/1.1" |
$status | 状态码 | 200 |
$body_bytes_sent | 响应体大小 | 1234 |
$http_referer | 来源页面 | "http://google.com" |
$http_user_agent | 用户代理 | "Mozilla/5.0..." |
$http_x_forwarded_for | 代理IP | "1.2.3.4, 5.6.7.8" |
access_log /var/log/nginx/access.log main; # 访问日志路径和格式sendfile on; # 使用内核的sendfile系统调用tcp_nopush on; # 在sendfile开启时,等数据包填满再发送 tcp_nodelay on; # 禁用Nagle算法,小数据包立即发送看似矛盾,实际配合:
tcp_nopush+sendfile:适用于大文件,减少数据包数量tcp_nodelay:适用于小数据,降低延迟keepalive_timeout 65; # 长连接保持65秒HTTP Keep-Alive工作流程:
客户端: GET /page1 服务器: 响应页面1 ↓ (65秒内) 客户端: GET /page2 ← 复用TCP连接 服务器: 响应页面2client_max_body_size 20m; # 最大上传文件20MB413 Request Entity Too Largegzip on; # 开启Gzip压缩 gzip_comp_level 6; # 压缩级别1-9(6是平衡选择) gzip_types text/plain text/css application/json;压缩效果对比:
原始文件: index.html 10KB 压缩后: index.html.gz 3KB# 传输减少70%未列出的常见类型:
# 建议补充 gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml font/woff font/woff2;upstream backend { server 192.168.1.100:8080 weight=3; # 权重3,处理30%请求 server 192.168.1.101:8080; # 权重1,处理10%请求 server 192.168.1.102:8080 backup; # 备份服务器 }负载均衡算法:
| 算法 | 配置 | 适用场景 |
|---|---|---|
| 轮询(默认) | 默认 | 服务器性能相近 |
| 加权轮询 | weight=N | 服务器性能不同 |
| IP哈希 | ip_hash | 需要会话保持 |
| 最少连接 | least_conn | 长连接场景 |
请求分发示例:
请求1 → 192.168.1.100 (权重3) 请求2 → 192.168.1.100 请求3 → 192.168.1.100 请求4 → 192.168.1.101 (权重1) 请求5 → 192.168.1.100 ... 备份服务器仅在主服务器宕机时使用upstream backend { server 192.168.1.100:8080 max_fails=3 fail_timeout=30s; server 192.168.1.101:8080 max_fails=3 fail_timeout=30s; }max_fails=3:连续失败3次标记为不可用fail_timeout=30s:30秒后重新尝试# 建议添加 server_tokens off; # 隐藏Nginx版本 client_body_buffer_size 128k; # 请求体缓冲区 client_header_buffer_size 4k; # 请求头缓冲区 large_client_header_buffers 4 8k; # 大请求头缓冲区# 文件缓存 open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; # 连接池优化 keepalive_requests 100; # 每个连接最大请求数gzip on; gzip_vary on; # 添加Vary头,代理缓存 gzip_proxied any; # 对所有代理请求压缩 gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 1024; # 小于1KB不压缩 gzip_types text/plain text/css application/json application/javascript application/xml text/xml application/xml+rss text/javascript image/svg+xml font/woff font/woff2;# 按天分割日志 map $time_iso8601 $logdate { '~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd; default 'nodate'; } access_log /var/log/nginx/access-$logdate.log main;客户端请求 ↓ Nginx接收 ↓ 日志记录 → access.log ↓ 检查MIME类型 → mime.types ↓ [大文件] sendfile传输 → 零拷贝 [小文件] 常规传输 ↓ [可压缩] Gzip压缩 → 减少带宽 [不可压缩] 直接发送 ↓ [需要代理] → upstream负载均衡 [静态文件] → 直接响应 ↓ TCP优化 → tcp_nopush/tcp_nodelay ↓ 保持连接65秒 → keepalive_timeout ↓ 返回响应http { # 当前配置 + 静态文件优化 sendfile on; tcp_nopush on; gzip on; server { root /var/www/html; index index.html; } }http { # 当前配置 + 超时控制 proxy_connect_timeout 5s; proxy_read_timeout 30s; proxy_send_timeout 30s; upstream api_servers { least_conn; # 最少连接算法 server api1:8080; server api2:8080; } }http { # 当前配置 + 大文件支持 client_max_body_size 100m; # 禁用某些目录的访问 location ~ /\. { deny all; } }