LNMP(Linux+Nginx+MySQL+PHP)架构的缓存策略需覆盖**Nginx(反向代理/静态资源)、PHP(脚本执行)、MySQL(数据库查询)**三大核心组件,以下是具体配置步骤及优化建议:
Nginx的缓存分为代理缓存(针对后端动态内容)和静态资源缓存(针对图片、CSS、JS等静态文件),两者均能显著减少重复请求的响应时间。
代理缓存通过proxy_cache模块缓存后端PHP-FPM或应用服务器的响应,适用于动态页面(如WordPress文章、用户动态)。
定义缓存路径与参数:在http块中添加proxy_cache_path指令,设置缓存存储路径、键区大小、最大缓存容量及失效规则。
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
}
参数说明:
levels=1:2:缓存目录层级(1级目录+2级子目录,避免单目录文件过多);keys_zone=my_cache:10m:缓存区域名称(my_cache)及共享内存大小(10MB,用于存储缓存键);max_size=1g:缓存最大容量(1GB),超过后自动清理旧文件;inactive=60m:缓存文件60分钟未被访问则自动删除。启用代理缓存:在server或location块中添加以下配置,指定缓存区域、缓存键及有效期。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://unix:/var/run/php/php7.4-fpm.sock; # 后端PHP-FPM地址
proxy_cache my_cache;
proxy_cache_key "$scheme$proxy_host$request_uri"; # 缓存键(包含协议、主机名、请求URI)
proxy_cache_valid 200 302 10m; # 200/302状态码缓存10分钟
proxy_cache_valid 404 1m; # 404状态码缓存1分钟
add_header X-Proxy-Cache $upstream_cache_status; # 添加缓存状态头(HIT/MISS/BYPASS)
}
}
静态资源(如图片、CSS、JS)无需动态生成,可通过expires指令设置长期缓存,减少服务器负载。
server {
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 30d; # 缓存30天
add_header Cache-Control "public, no-transform"; # 允许公共缓存(如CDN)
}
}
PHP脚本每次请求都需编译执行,通过OPcache(Zend官方扩展)可缓存编译后的字节码,大幅提升执行效率;对于复杂数据(如用户会话、热点数据),可使用Redis或Memcached作为外部缓存。
OPcache是PHP 7.2+的内置扩展,无需额外安装,只需在php.ini中启用并配置。
php.ini(路径通常为/etc/php/7.4/fpm/php.ini):[opcache]
zend_extension=opcache.so # 启用扩展(PHP 7.2+默认包含)
opcache.enable=1 # 开启OPcache
opcache.memory_consumption=128 # 内存占用(MB,根据服务器内存调整)
opcache.interned_strings_buffer=8 # 内部字符串缓冲区大小
opcache.max_accelerated_files=4000 # 最大加速文件数(需覆盖项目所有PHP文件)
opcache.revalidate_freq=60 # 文件修改后60秒重新验证(0为每次请求都验证,生产环境建议>0)
opcache.fast_shutdown=1 # 快速关闭(提升脚本结束时的清理效率)
sudo systemctl restart php7.4-fpm
若需缓存数据库查询结果、用户会话等复杂数据,可安装Redis或Memcached扩展。
sudo apt install redis-server php-redis
php.ini中添加):extension=redis.so
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$cacheKey = 'user_123_profile';
if ($redis->exists($cacheKey)) {
$userData = $redis->get($cacheKey);
} else {
// 从数据库获取数据
$userData = $db->query("SELECT * FROM users WHERE id = 123")->fetch();
$redis->set($cacheKey, $userData, 3600); // 缓存1小时
}
MySQL的缓存主要针对数据库查询和InnoDB表数据,优化查询性能。
查询缓存可缓存SELECT查询的结果,但MySQL 8.0已移除该功能,建议升级至MySQL 8.0+并使用Redis替代。
my.cnf):[mysqld]
query_cache_type=1 # 开启查询缓存(1=开启,0=关闭)
query_cache_size=64M # 缓存大小(根据查询量调整)
query_cache_limit=2M # 单个查询结果最大缓存大小
InnoDB缓冲池是MySQL最重要的缓存,用于缓存表数据和索引,减少磁盘IO。
my.cnf):[mysqld]
innodb_buffer_pool_size=1G # 建议设置为服务器内存的50%-70%(如16GB内存设为8G-12G)
innodb_buffer_pool_instances=8 # 缓冲池实例数(并发高时设置,提升并发性能)
innodb_log_file_size=256M # 日志文件大小(提升写入性能)
innodb_log_buffer_size=64M # 日志缓冲区大小
expires指令设置静态资源的Cache-Control头,让浏览器缓存资源(如expires 30d;)。# 清理Nginx缓存(保留最近7天的文件)
find /var/cache/nginx -type f -mtime +7 -delete
# 清理Redis缓存(可选)
redis-cli flushall
以上配置需根据服务器硬件资源(内存、CPU)和网站流量(动态/静态请求比例)进行调整,建议配置后通过ab(Apache Benchmark)或wrk工具进行压力测试,优化缓存命中率。