lolly/docs/07-nginx-compression-caching.md
xfy 9cae5ad8cf chore(init): initialize project with nginx documentation
- Add Go module initialization (go 1.26)
- Add comprehensive NGINX documentation covering:
  - Overview, installation, HTTP core module
  - Proxy/load balancing, SSL/TLS, URL rewrite
  - Compression/caching, logging/monitoring
  - Security, TCP/UDP stream, mail proxy
  - Performance tuning, Git commit guide
- Add standard Go .gitignore

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-02 11:45:53 +08:00

475 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NGINX 压缩与缓存指南
## 1. Gzip 压缩配置
### 基础配置
```nginx
http {
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_vary on;
}
```
### 指令详解
| 指令 | 说明 | 默认值 |
|------|------|--------|
| `gzip` | 启用/禁用压缩 | off |
| `gzip_buffers` | 压缩缓冲区数量和大小 | 32 4k 或 16 8k |
| `gzip_comp_level` | 压缩级别1-9 | 1 |
| `gzip_disable` | 禁用压缩的 User-Agent 正则 | - |
| `gzip_http_version` | 最小 HTTP 版本 | 1.1 |
| `gzip_min_length` | 最小压缩长度 | 20 |
| `gzip_proxied` | 代理请求压缩条件 | off |
| `gzip_types` | 压缩的 MIME 类型 | text/html |
| `gzip_vary` | 添加 Vary 头 | off |
### 压缩级别选择
| 级别 | 压缩率 | CPU 消耗 | 推荐场景 |
|------|--------|----------|----------|
| 1 | 低 | 低 | CPU 受限环境 |
| 4-6 | 中 | 中 | **推荐(平衡)** |
| 9 | 高 | 高 | 静态内容预压缩 |
### gzip_proxied 参数
| 参数 | 说明 |
|------|------|
| `off` | 禁用所有代理请求压缩 |
| `any` | 压缩所有代理请求 |
| `expired` | Expires 头表明过期的响应 |
| `no-cache` | Cache-Control: no-cache |
| `no-store` | Cache-Control: no-store |
| `private` | Cache-Control: private |
| `auth` | 包含 Authorization 头 |
### 完整配置示例
```nginx
http {
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_proxied any;
gzip_vary on;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
application/x-javascript;
gzip_disable "msie6";
# 排除已压缩文件
gzip_types ~ "image/(gif|jpg|jpeg|png|webp)|video/.*|application/pdf|application/zip";
server {
location / {
# 继承全局配置
}
}
}
```
### 压缩变量
`$gzip_ratio`:压缩率(原始大小/压缩后大小)
```nginx
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
```
---
## 2. 预压缩文件gzip_static
### 启用预压缩
```nginx
location / {
gzip_static on;
gzip_proxied any;
}
```
### 工作原理
- 请求 `/style.css`nginx 检查 `/style.css.gz` 是否存在
- 如果存在且客户端支持 gzip直接发送预压缩文件
- 避免实时压缩的 CPU 开销
### 生成预压缩文件
```bash
# 批量生成
find /var/www/html -type f -name "*.css" -exec gzip -k {} \;
find /var/www/html -type f -name "*.js" -exec gzip -k {} \;
```
### 配置选项
```nginx
gzip_static on; # 发送预压缩文件
gzip_static always; # 总是发送预压缩文件(不检查客户端支持)
gzip_static off; # 禁用
```
---
## 3. Brotli 压缩(需模块)
### 安装模块
```bash
# 编译时添加
--add-module=/path/to/ngx_brotli
```
### 配置示例
```nginx
http {
# Brotli 压缩
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml;
brotli_min_length 1000;
# 同时启用 gzip 作为后备
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript;
}
```
---
## 4. 代理缓存配置
### 缓存路径定义
```nginx
http {
proxy_cache_path /data/nginx/cache
levels=1:2 # 目录层级a/bc/abc...
keys_zone=main:10m # 共享内存区名称和大小
max_size=1g # 缓存最大大小
inactive=60m # 非活动数据保留时间
use_temp_path=off # 临时文件存放位置
manager_files=100 # 缓存管理器每次处理文件数
manager_threshold=500ms;
}
```
### 目录层级说明
`levels=1:2` 表示:
- 第一级16 个目录0-f
- 第二级256 个目录00-ff
缓存文件路径示例:`/data/nginx/cache/a/bc/abcdef...`
### 启用缓存
```nginx
server {
location / {
proxy_cache main;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_pass http://backend;
}
}
```
### 缓存键定义
```nginx
# 默认
proxy_cache_key $scheme$proxy_host$request_uri;
# 自定义
proxy_cache_key "$host$request_uri $cookie_user";
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_key "$server_name$uri$is_args$args";
```
### 缓存有效期
```nginx
# 按响应码设置
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
# 使用响应头控制
# X-Accel-Expires: 有效期(秒)
# Expires: HTTP 过期时间
# Cache-Control: 缓存控制
```
### 条件缓存
```nginx
# 不从缓存获取
proxy_cache_bypass $cookie_nocache $arg_nocache;
# 不保存到缓存
proxy_no_cache $http_pragma $http_authorization;
# 示例:登录用户不缓存
map $cookie_user $skip_cache {
default 0;
"" 1; # 未登录用户不缓存
}
location / {
proxy_cache main;
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
}
```
### 使用过期缓存
```nginx
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
```
| 条件 | 说明 |
|------|------|
| `error` | 与后端通信出错 |
| `timeout` | 超时 |
| `invalid_header` | 无效响应头 |
| `updating` | 缓存正在更新 |
| `http_XXX` | 后端返回指定状态码 |
### 缓存锁
```nginx
proxy_cache_lock on; # 同时只有一个请求填充缓存
proxy_cache_lock_timeout 5s; # 锁超时时间
proxy_cache_lock_age 5s; # 允许新请求时间
```
### 后台更新
```nginx
proxy_cache_background_update on; # 后台更新过期缓存
```
---
## 5. FastCGI 缓存
### 配置示例
```nginx
http {
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=fastcgi:10m
inactive=60m
max_size=100m;
server {
location ~ \.php$ {
fastcgi_cache fastcgi;
fastcgi_cache_key "$request_method$host$request_uri";
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_methods GET HEAD;
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
```
---
## 6. 缓存清除(商业版)
```nginx
map $request_method $purge_method {
PURGE 1;
default 0;
}
server {
location / {
proxy_cache main;
proxy_cache_key $uri;
proxy_cache_purge $purge_method;
}
}
# 清除缓存
# curl -X PURGE http://example.com/path/to/file
```
---
## 7. 静态文件缓存
### 浏览器缓存
```nginx
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt|woff)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
location ~* \.(html|htm)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
# 禁用缓存
location /api/ {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
expires 0;
}
```
### expires 指令
```nginx
expires 30d; # 30 天
expires 1h; # 1 小时
expires epoch; # 1970-01-01不缓存
expires max; # 最大值2037 年)
expires off; # 不修改(默认)
```
### try_files + 缓存
```nginx
location / {
try_files $uri @backend;
}
location @backend {
proxy_cache main;
proxy_cache_valid 200 10m;
proxy_pass http://backend;
}
```
---
## 8. 文件描述符缓存
```nginx
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
```
| 参数 | 说明 |
|------|------|
| `max` | 缓存最大文件数 |
| `inactive` | 非活动文件移除时间 |
| `valid` | 检查文件是否存在的间隔 |
| `min_uses` | 保持打开的最少使用次数 |
---
## 9. 缓存状态监控
### stub_status 模块
```nginx
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
```
输出示例:
```
Active connections: 10
server accepts handled requests
100 100 200
Reading: 0 Writing: 1 Waiting: 9
```
### 缓存命中率计算
```nginx
log_format cache_status '$remote_addr - [$time_local] '
'"$request" $status '
'cache: $upstream_cache_status';
# 状态值HIT, MISS, BYPASS, EXPIRED, STALE, UPDATING, REVALIDATED
```
---
## 10. 缓存最佳实践
### 缓存策略建议
| 内容类型 | 缓存时间 | 策略 |
|----------|----------|------|
| 静态资源图片、CSS、JS | 30 天 + immutable | 浏览器缓存 |
| HTML 页面 | 1 小时 | 协商缓存 |
| API 响应 | 按需 | 代理缓存 |
| 用户特定内容 | 不缓存 | 动态生成 |
### 避免缓存问题
```nginx
# 避免缓存POST请求
proxy_cache_methods GET HEAD;
# 避免缓存带查询参数的请求
proxy_cache_key "$host$request_uri";
# 避免缓存大文件
proxy_max_temp_file_size 0;
# 动态内容禁用缓存
location /api/ {
proxy_cache off;
add_header Cache-Control "no-store";
}
```
### 缓存预热
```bash
# 预热缓存脚本
#!/bin/bash
urls=(
"https://example.com/page1"
"https://example.com/page2"
)
for url in "${urls[@]}"; do
curl -s "$url" > /dev/null &
done
wait
```