Nginx Cache缓存网站数据实践

1. 概述

1.1 Nginx缓存的重要性

Nginx缓存是提升网站性能的关键技术,通过将静态对象(图片、CSS、JS等)缓存到本地,可以显著减少后端服务器的压力,提高响应速度,改善用户体验。Nginx的proxy_cache功能可以替代Squid等专业缓存服务器,实现高效的缓存管理。

缓存的价值

  • 性能提升:减少后端服务器压力,提高响应速度
  • 带宽节省:减少网络传输,节省带宽成本
  • 用户体验:加快页面加载速度,提升用户体验
  • 高可用性:后端故障时,缓存仍可提供服务

1.2 Nginx缓存机制

Nginx缓存类型

  1. proxy_cache:反向代理缓存,缓存后端服务器响应
  2. fastcgi_cache:FastCGI缓存,缓存PHP等动态内容
  3. uwsgi_cache:uWSGI缓存,缓存Python应用响应
  4. scgi_cache:SCGI缓存,缓存SCGI应用响应

本文重点:proxy_cache反向代理缓存

1.3 本文内容结构

本文将从以下几个方面详细介绍Nginx缓存实践:

  1. 环境准备:Nginx安装和基础配置
  2. 缓存配置:proxy_cache详细配置
  3. 缓存优化:性能优化和最佳实践
  4. 缓存监控:缓存命中率监控
  5. 故障排查:常见问题和解决方案
  6. 生产环境实践:企业级缓存方案

2. 环境准备

2.1 系统要求

操作系统

  • CentOS 6.x / 7.x
  • RHEL 6.x / 7.x
  • Ubuntu 14.04+
  • Debian 7+

软件要求

  • Nginx 1.0+
  • 推荐Nginx 1.10+(功能更完善)

2.2 安装Nginx

2.2.1 使用EPEL源安装

CentOS/RHEL系统

1
2
3
4
5
6
7
8
9
10
11
# 添加EPEL源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo

# 或CentOS 7
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

# 安装Nginx
yum install nginx -y

# 查看Nginx文件位置
rpm -ql nginx

输出示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/usr/bin/nginx
/usr/lib64/nginx
/usr/sbin/nginx
/var/cache/nginx
/var/log/nginx

2.2.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
# 安装依赖
yum install gcc gcc-c++ pcre-devel zlib-devel openssl-devel -y

# 下载Nginx
cd /soft/src
wget http://nginx.org/download/nginx-1.18.0.tar.gz

# 解压
tar xf nginx-1.18.0.tar.gz
cd nginx-1.18.0

# 编译安装
./configure \
--prefix=/application/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_secure_link_module

make && make install

# 创建软链接
ln -s /application/nginx-1.18.0 /application/nginx

2.3 基础配置

2.3.1 创建基础配置文件

编辑nginx.conf

1
vim /etc/nginx/nginx.conf

基础配置

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
user              nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

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"';

sendfile on;
keepalive_timeout 65;

server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}

2.3.2 启动和验证

1
2
3
4
5
6
7
8
9
# 启动Nginx
nginx

# 或使用systemd
systemctl start nginx
systemctl enable nginx

# 检查端口
netstat -tunlp | grep nginx

输出示例

1
tcp        0      0 0.0.0.0:80           0.0.0.0:*               LISTEN      1043/nginx

测试访问

1
2
# 测试HTTP响应
curl -I http://192.168.16.199

输出示例

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Mon, 14 Sep 2015 09:40:53 GMT
Content-Type: text/html
Content-Length: 3698
Last-Modified: Tue, 16 Jun 2015 21:34:15 GMT
Connection: keep-alive
Accept-Ranges: bytes

2.3.3 准备测试文件

查看默认页面

1
tree /usr/share/nginx/html/

目录结构

1
2
3
4
5
6
/usr/share/nginx/html/
├── 404.html
├── 50x.html
├── index.html
├── nginx-logo.png
└── poweredby.png

说明:默认页面包含2张图片,正好用于缓存测试。


3. 配置Cache

3.1 创建目录并挂载tmpfs

3.1.1 创建缓存目录

1
2
3
4
5
6
7
# 创建缓存目录和临时目录
mkdir -p /tmp/ngx_tmp
mkdir -p /tmp/ngx_cache

# 或使用更规范的路径
mkdir -p /var/cache/nginx/tmp
mkdir -p /var/cache/nginx/cache

3.1.2 挂载tmpfs加速缓存

为什么使用tmpfs

  • 缓存存放在磁盘,磁盘IO会影响缓存速度
  • tmpfs是基于内存的文件系统,读写速度极快
  • 适合缓存热点数据

挂载tmpfs

1
2
3
4
5
# 挂载tmpfs到缓存目录
mount -t tmpfs -o size=100M tmpfs /tmp/ngx_cache

# 验证挂载
mount | grep tmpfs

输出示例

1
2
tmpfs on /dev/shm type tmpfs (rw)
tmpfs on /tmp/ngx_cache type tmpfs (rw,size=100M)

永久挂载(可选)

1
2
3
4
5
# 编辑/etc/fstab
echo "tmpfs /tmp/ngx_cache tmpfs defaults,size=100M 0 0" >> /etc/fstab

# 测试挂载
mount -a

注意事项

  • tmpfs大小根据服务器内存调整
  • 建议设置为可用内存的10-20%
  • 生产环境建议使用SSD磁盘,性能更好

3.2 配置缓存目录和键空间

3.2.1 proxy_cache_path指令

在http块中配置

1
2
3
4
5
6
7
8
http {
# 缓存配置
proxy_cache_path /tmp/ngx_cache
levels=1:2
keys_zone=cache_one:100m
inactive=1d
max_size=5g;
}

参数说明

参数 说明 示例值
proxy_cache_path 缓存目录路径 /tmp/ngx_cache
levels 缓存目录层级 1:2(一级1个字符,二级2个字符)
keys_zone 键空间名称和大小 cache_one:100m
inactive 缓存失效时间 1d(1天)
max_size 最大缓存大小 5g(5GB)

levels说明

  • levels=1:2:目录结构为 /tmp/ngx_cache/a/bc/xxx
  • levels=1:1:1:目录结构为 /tmp/ngx_cache/a/b/c/xxx
  • 建议使用2-3级目录,避免单目录文件过多

keys_zone说明

  • cache_one:键空间名称,在location中引用
  • 100m:键空间大小,存储缓存键的元数据
  • 1MB可以存储约8000个键

3.2.2 完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
http {
# 缓存配置
proxy_cache_path /tmp/ngx_cache
levels=1:2
keys_zone=cache_one:100m
inactive=1d
max_size=5g
use_temp_path=off;

# 临时文件路径(可选)
proxy_temp_path /tmp/ngx_tmp;
}

use_temp_path说明

  • use_temp_path=off:临时文件直接写入缓存目录
  • use_temp_path=on:临时文件写入proxy_temp_path
  • 建议设置为off,减少磁盘IO

3.3 配置反向代理

3.3.1 配置upstream

1
2
3
4
5
6
7
8
9
http {
# 定义后端服务器组
upstream server_pool {
server 127.0.0.1:8080;
# 可以添加多个后端服务器
# server 192.168.1.100:8080 weight=2;
# server 192.168.1.101:8080;
}
}

3.3.2 配置后端服务器(测试用)

配置8080端口的server

1
2
3
4
5
6
7
8
9
10
server {
listen 8080;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

access_log /var/log/nginx/backend_access.log main;
}

3.3.3 配置反向代理和缓存

在80端口的server中配置

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
server {
listen 80;

location / {
# 反向代理
proxy_pass http://server_pool;

# 错误处理
proxy_next_upstream http_502 http_504 error timeout invalid_header;

# 缓存配置
proxy_cache cache_one; # 使用键空间
proxy_cache_valid 200 304 12h; # 200和304状态码缓存12小时
proxy_cache_valid 301 302 1m; # 301和302状态码缓存1分钟
proxy_cache_valid any 1m; # 其他状态码缓存1分钟
proxy_cache_key $host$uri$is_args$args; # 缓存键格式

# 代理头信息
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_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;

# 过期时间(浏览器缓存)
expires 1d;
}

access_log /var/log/nginx/cache_access.log main;
}

缓存参数说明

参数 说明 示例值
proxy_cache 指定使用的键空间 cache_one
proxy_cache_valid 不同状态码的缓存时间 200 304 12h
proxy_cache_key 缓存键的格式 $host$uri$is_args$args
proxy_cache_use_stale 后端错误时使用过期缓存 error timeout
proxy_cache_background_update 后台更新缓存 on
proxy_cache_lock 缓存更新时加锁 on

3.3.4 完整nginx.conf配置

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
user              nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

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"'
' "addr:$upstream_addr-status:$upstream_status-cachestatus:$upstream_cache_status"';

sendfile on;
keepalive_timeout 65;

# 缓存配置
proxy_cache_path /tmp/ngx_cache
levels=1:2
keys_zone=cache_one:100m
inactive=1d
max_size=5g
use_temp_path=off;

# 后端服务器组
upstream server_pool {
server 127.0.0.1:8080;
}

# 反向代理服务器
server {
listen 80;

location / {
proxy_pass http://server_pool;
proxy_next_upstream http_502 http_504 error timeout invalid_header;

proxy_cache cache_one;
proxy_cache_valid 200 304 12h;
proxy_cache_valid 301 302 1m;
proxy_cache_valid any 1m;
proxy_cache_key $host$uri$is_args$args;

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_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;

expires 1d;
}

access_log /var/log/nginx/cache_access.log main;
}

# 后端服务器(测试用)
server {
listen 8080;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
}

3.4 配置日志

3.4.1 日志格式配置

为了观察缓存命中情况,需要记录缓存相关变量

1
2
3
4
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
' "addr:$upstream_addr-status:$upstream_status-cachestatus:$upstream_cache_status"';

日志变量说明

  • $upstream_addr:后端服务器地址
  • $upstream_status:后端服务器返回的状态码
  • $upstream_cache_status:缓存命中状态

缓存状态值

  • MISS:缓存未命中,从后端获取
  • HIT:缓存命中,直接返回缓存
  • EXPIRED:缓存过期,从后端获取
  • STALE:使用过期缓存
  • UPDATING:缓存正在更新
  • REVALIDATED:缓存已重新验证
  • BYPASS:绕过缓存

3.4.2 应用日志格式

1
2
3
4
5
server {
listen 80;
access_log /var/log/nginx/cache_access.log main;
# ...
}

3.4.3 重新加载配置

1
2
3
4
5
6
7
8
# 测试配置
nginx -t

# 重新加载配置
nginx -s reload

# 或使用systemd
systemctl reload nginx

3.5 监测缓存

3.5.1 使用inotify监测缓存文件

安装inotify-tools

1
2
3
4
5
# CentOS/RHEL
yum install inotify-tools -y

# Ubuntu/Debian
apt-get install inotify-tools -y

监测缓存目录

1
2
# 实时监测缓存目录的文件事件
inotifywait -mrq /tmp/ngx_cache/

访问网站触发缓存

1
2
3
4
# 在另一个终端访问网站
curl http://192.168.16.199/
curl http://192.168.16.199/nginx-logo.png
curl http://192.168.16.199/poweredby.png

监测输出示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/tmp/ngx_cache/ CREATE,ISDIR 6
/tmp/ngx_cache/ OPEN,ISDIR 6
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 6
/tmp/ngx_cache/ CREATE,ISDIR 1
/tmp/ngx_cache/ OPEN,ISDIR 1
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 1
/tmp/ngx_cache/ CREATE,ISDIR 3
/tmp/ngx_cache/ OPEN,ISDIR 3
/tmp/ngx_cache/ CLOSE_NOWRITE,CLOSE,ISDIR 3
/tmp/ngx_cache/3/ CREATE,ISDIR fd
/tmp/ngx_cache/3/ OPEN,ISDIR fd
/tmp/ngx_cache/3/ CLOSE_NOWRITE,CLOSE,ISDIR fd
/tmp/ngx_cache/3/fd/ CREATE dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ OPEN dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MODIFY dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ CLOSE_WRITE,CLOSE dd404cd351f6b9efb072e5806efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MOVED_FROM dd404cd351f6b9efb072e5806dc2efd3.0000000026
/tmp/ngx_cache/3/fd/ MOVED_TO dd404cd351f6b9efb072e5806dc2efd3

说明

  • 最后几行显示图片已缓存到目录中
  • 文件先创建临时文件,然后移动到最终位置

3.5.2 查看缓存文件

1
2
3
4
5
6
7
8
# 查看缓存目录结构
tree /tmp/ngx_cache/

# 查看缓存文件
ls -lh /tmp/ngx_cache/3/fd/

# 查看缓存文件内容(如果是文本文件)
cat /tmp/ngx_cache/3/fd/dd404cd351f6b9efb072e5806dc2efd3

3.5.3 查看日志分析缓存命中

1
2
3
4
5
# 查看访问日志
tail -f /var/log/nginx/cache_access.log

# 统计缓存命中率
grep "cachestatus" /var/log/nginx/cache_access.log | awk '{print $NF}' | sort | uniq -c

输出示例

1
2
10 cachestatus:MISS
20 cachestatus:HIT

计算命中率

  • 命中率 = HIT次数 / (HIT次数 + MISS次数) × 100%
  • 示例:20 / (20 + 10) × 100% = 66.7%

4. 缓存优化

4.1 缓存键优化

4.1.1 缓存键格式

默认格式

1
proxy_cache_key $scheme$proxy_host$request_uri;

常用格式

1
2
3
4
5
6
7
8
# 包含主机、URI和参数
proxy_cache_key $host$uri$is_args$args;

# 包含协议、主机、URI和参数
proxy_cache_key $scheme$host$uri$is_args$args;

# 包含Cookie(用于个性化内容)
proxy_cache_key $host$uri$is_args$args$http_cookie;

优化建议

  • 根据业务需求选择合适的键格式
  • 避免包含变化频繁的参数(如时间戳)
  • 个性化内容需要包含用户标识

4.2 缓存时间优化

4.2.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
location / {
proxy_cache cache_one;

# 静态资源缓存时间长
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_cache cache_one;
proxy_cache_valid 200 304 7d;
expires 7d;
}

# HTML缓存时间短
location ~* \.html$ {
proxy_cache cache_one;
proxy_cache_valid 200 304 1h;
expires 1h;
}

# 动态内容不缓存或缓存时间很短
location ~* \.(php|jsp|do)$ {
proxy_cache cache_one;
proxy_cache_valid 200 304 1m;
expires 1m;
}
}

4.3 缓存条件优化

4.3.1 根据请求头决定是否缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
location / {
proxy_cache cache_one;

# 只缓存GET和HEAD请求
proxy_cache_methods GET HEAD;

# 不缓存带Cookie的请求(可选)
proxy_cache_bypass $http_cookie;

# 不缓存带特定参数的请求
proxy_cache_bypass $arg_nocache;

# 不缓存POST请求
proxy_no_cache $request_method;
}

4.4 缓存清理

4.4.1 手动清理缓存

1
2
3
4
5
# 删除整个缓存目录
rm -rf /tmp/ngx_cache/*

# 删除特定文件
find /tmp/ngx_cache/ -name "*特定文件名*" -delete

4.4.2 使用purge模块清理

编译Nginx时添加purge模块

1
2
3
4
5
6
7
8
# 下载purge模块
cd /soft/src
git clone https://github.com/FRiCKLE/ngx_cache_purge.git

# 编译时添加模块
./configure \
--add-module=/soft/src/ngx_cache_purge \
# ... 其他参数

配置purge

1
2
3
4
5
6
7
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;

proxy_cache_purge cache_one $host$1$is_args$args;
}

使用purge清理

1
2
# 清理特定URL的缓存
curl -X PURGE http://192.168.16.199/nginx-logo.png

5. 缓存监控

5.1 日志分析脚本

5.1.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
cat > /usr/local/bin/nginx_cache_stats.sh << 'EOF'
#!/bin/bash

LOG_FILE="/var/log/nginx/cache_access.log"

if [ ! -f "$LOG_FILE" ]; then
echo "Error: Log file not found: $LOG_FILE"
exit 1
fi

echo "=== Nginx Cache Statistics ==="
echo ""

# 统计缓存状态
echo "Cache Status Distribution:"
grep "cachestatus" $LOG_FILE | awk -F'cachestatus:' '{print $2}' | sort | uniq -c | sort -rn

echo ""
echo "Cache Hit Rate:"

# 计算命中率
TOTAL=$(grep "cachestatus" $LOG_FILE | wc -l)
HIT=$(grep "cachestatus:HIT" $LOG_FILE | wc -l)
MISS=$(grep "cachestatus:MISS" $LOG_FILE | wc -l)

if [ $TOTAL -gt 0 ]; then
HIT_RATE=$(echo "scale=2; $HIT * 100 / $TOTAL" | bc)
echo "Total Requests: $TOTAL"
echo "Cache Hits: $HIT"
echo "Cache Misses: $MISS"
echo "Hit Rate: ${HIT_RATE}%"
else
echo "No cache data found"
fi
EOF

chmod +x /usr/local/bin/nginx_cache_stats.sh

# 使用
/usr/local/bin/nginx_cache_stats.sh

5.2 缓存文件监控

5.2.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
cat > /usr/local/bin/nginx_cache_size.sh << 'EOF'
#!/bin/bash

CACHE_DIR="/tmp/ngx_cache"

if [ ! -d "$CACHE_DIR" ]; then
echo "Error: Cache directory not found: $CACHE_DIR"
exit 1
fi

echo "=== Nginx Cache Directory Size ==="
echo ""

# 目录大小
SIZE=$(du -sh $CACHE_DIR | awk '{print $1}')
echo "Cache Directory Size: $SIZE"

# 文件数量
COUNT=$(find $CACHE_DIR -type f | wc -l)
echo "Cache File Count: $COUNT"

# 目录使用率(如果是tmpfs)
if mount | grep -q "$CACHE_DIR.*tmpfs"; then
USAGE=$(df -h $CACHE_DIR | tail -1 | awk '{print $5}')
echo "Cache Directory Usage: $USAGE"
fi
EOF

chmod +x /usr/local/bin/nginx_cache_size.sh

# 使用
/usr/local/bin/nginx_cache_size.sh

5.3 Prometheus监控(可选)

5.3.1 使用nginx-prometheus-exporter

1
2
3
4
5
6
7
8
# 下载exporter
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.9.0/nginx-prometheus-exporter_0.9.0_linux_amd64.tar.gz

# 解压
tar xf nginx-prometheus-exporter_0.9.0_linux_amd64.tar.gz

# 运行exporter
./nginx-prometheus-exporter -nginx.scrape-uri=http://localhost:8080/stub_status

6. 故障排查

6.1 常见问题

6.1.1 缓存不生效

问题:访问后缓存目录没有文件

排查步骤

1
2
3
4
5
6
7
8
9
10
11
# 1. 检查配置语法
nginx -t

# 2. 检查缓存目录权限
ls -ld /tmp/ngx_cache

# 3. 检查日志
tail -f /var/log/nginx/cache_access.log | grep cachestatus

# 4. 检查后端响应头
curl -I http://127.0.0.1:8080/

可能原因

  • 后端返回Cache-Control: no-cache
  • 后端返回Set-Cookie
  • 缓存目录权限不足

解决方案

1
2
3
4
5
6
# 忽略某些响应头
proxy_ignore_headers "Set-Cookie";
proxy_ignore_headers "Cache-Control";

# 或强制缓存
proxy_cache_valid any 1h;

6.1.2 缓存命中率低

问题:缓存命中率很低

排查步骤

1
2
# 查看缓存状态分布
grep "cachestatus" /var/log/nginx/cache_access.log | awk -F'cachestatus:' '{print $2}' | sort | uniq -c

可能原因

  • 缓存键包含变化频繁的参数
  • 缓存时间设置过短
  • 请求URL变化频繁

解决方案

  • 优化缓存键格式
  • 增加缓存时间
  • 规范化URL

6.1.3 缓存目录空间不足

问题:缓存目录空间不足

排查步骤

1
2
3
4
5
# 检查目录大小
du -sh /tmp/ngx_cache

# 检查磁盘空间
df -h /tmp/ngx_cache

解决方案

1
2
3
4
5
6
7
# 清理过期缓存
find /tmp/ngx_cache/ -type f -mtime +1 -delete

# 或增加缓存目录大小
# 如果使用tmpfs,重新挂载
umount /tmp/ngx_cache
mount -t tmpfs -o size=500M tmpfs /tmp/ngx_cache

7. 生产环境最佳实践

7.1 缓存策略

7.1.1 分层缓存策略

1
2
3
4
5
6
7
8
9
用户请求

CDN缓存(边缘节点)

Nginx缓存(反向代理层)

应用缓存(应用层)

数据库

7.1.2 缓存时间建议

内容类型 缓存时间 说明
静态图片 7-30天 很少变化
CSS/JS 1-7天 可能更新
HTML 1小时-1天 经常更新
动态内容 1-5分钟 实时性要求高

7.2 性能优化

7.2.1 使用SSD存储

1
2
3
# 生产环境建议使用SSD
# 挂载SSD到缓存目录
mount /dev/sdb1 /var/cache/nginx/cache

7.2.2 调整worker进程

1
2
3
4
5
6
7
# 根据CPU核心数设置
worker_processes auto;

# 每个worker的连接数
events {
worker_connections 4096;
}

7.3 高可用方案

7.3.1 缓存共享

使用NFS或分布式存储共享缓存

1
2
# 挂载NFS
mount -t nfs 192.168.1.100:/cache /var/cache/nginx/cache

7.3.2 缓存预热

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 预热脚本
cat > /usr/local/bin/cache_warmup.sh << 'EOF'
#!/bin/bash

URLS=(
"http://example.com/"
"http://example.com/css/style.css"
"http://example.com/js/app.js"
)

for url in "${URLS[@]}"; do
curl -s "$url" > /dev/null
echo "Warmed up: $url"
done
EOF

8. 总结

8.1 核心要点

  1. 缓存配置:proxy_cache_path和proxy_cache指令
  2. 缓存键:合理设置缓存键格式
  3. 缓存时间:根据内容类型设置缓存时间
  4. 缓存监控:监控缓存命中率和目录大小
  5. 性能优化:使用tmpfs或SSD加速缓存

8.2 架构师建议

  1. 缓存策略:分层缓存,合理设置缓存时间
  2. 性能优化:使用SSD存储,调整worker进程
  3. 监控告警:监控缓存命中率,设置告警阈值
  4. 故障处理:定期清理缓存,处理缓存问题

8.3 最佳实践

  1. 标准化:统一缓存配置标准
  2. 自动化:自动化缓存清理和预热
  3. 监控化:实时监控缓存状态
  4. 文档化:维护缓存配置文档

相关文章