我们在用户登录会话方面遇到了问题,这些问题是由于 nginx 配置文件导致的缓存。
我们的应用程序是用cakephp开发的。无法使用nginx停止缓存特定文件。
请查看以下 nginx conf 文件,并建议使用 nginx 处理用户登录会话的最佳方法
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 4024;
}
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 0;
keepalive_timeout 650;
types_hash_max_size 2048;
# gzip on;
# gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
index index.php;
fastcgi_cache_path /home/main_domain/public_html/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=600m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
server_name main_domain.com;
rewrite ^ http://www.main_domain.com$request_uri;
}
#server {
# server_name main_domain.com;
# return 301 $scheme://www.main_domain.com$request_uri;
#}
server {
listen 80;
server_name www.main_domain.com;
# root directive should be global
root /home/main_domain/public_html/;
index index.php index.html;
# set $no_cache 0;
access_log /home/main_domain/public_html/access.log;
error_log /home/main_domain/public_html/error.log;
location / {
try_files $uri $uri/ /index.php?$1;
# proxy_cache my_cache;
# proxy_pass http://main_domain2.com;
# proxy_cache_valid 200 302 60m;
# proxy_cache_valid 404 1m;
}
location ~* \favicon.ico$ {
expires 6m;
}
location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }
location ~ \.php$ {
try_files $uri =404;
# fastcgi_cache my_cache;
# fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
# fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
# add_header X-Fastcgi-Cache $upstream_cache_status;
# fastcgi_cache_bypass $no_cache; # Don't pull from cache based on $no_cache
# fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
# fastcgi_buffer_size 128k;
# fastcgi_buffers 256 4k;
# fastcgi_busy_buffers_size 256k;
# fastcgi_temp_file_write_size 256k;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/$fastcgi_script_name;
fastcgi_read_timeout 300;
}
}
server {
listen 80;
server_name www.subdomain1.main_domain.com;
# root directive should be global
root /home/main_domain/public_html/dev/subdomains/subdomain1/app/webroot;
index index.php index.html;
set $no_cache 0;
# location /users {
# try_files $uri $uri/ /index.php?$1;
# expires off;
# proxy_no_cache $no_cache;
# proxy_cache_bypass $no_cache;
if ($request_uri ~* "/users.*") {
set $no_cache 1;
}
# }
# if ($request_uri ~* "(/admin|/users|/login)") {
# set $no_cache 1;
# }
# proxy_no_cache $no_cache;
# proxy_cache_bypass $no_cache;
access_log /home/main_domain/public_html/dev/subdomains/subdomain1/access.log;
error_log /home/main_domain/public_html/dev/subdomains/subdomain1/error.log;
location /blog/ { try_files $uri $uri/ /blog/index.php?$args; }
location / {
try_files $uri $uri/ /index.php?$1;
# proxy_cache my_cache;
# proxy_pass http://main_domain2.com;
# proxy_cache_valid 200 302 60m;
# proxy_cache_valid 404 1m;
}
location ~* \favicon.ico$ {
expires 6m;
}
location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }
location ~ \.php$ {
try_files $uri =404;
fastcgi_cache my_cache;
fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
add_header X-Fastcgi-Cache $upstream_cache_status;
fastcgi_cache_bypass $no_cache; # Don't pull from cache based on $no_cache
fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
fastcgi_buffer_size 128k;
fastcgi_buffers 256 4k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/dev/subdomains/subdomain1/app/webroot$fastcgi_script_name;
}
}
server {
listen 80;
server_name subdomain2.main_domain.com;
rewrite ^ http://www.subdomain2.main_domain.com$1 permanent;
}
server {
listen 80;
server_name www.subdomain2.main_domain.com;
set $mobile_rewrite do_not_perform;
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino") {
set $mobile_rewrite perform;
}
if ($mobile_rewrite = perform) {
rewrite ^ http://m.main_domain.com$request_uri? redirect;
break;
}
# root directive should be global
root /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot;
index index.php index.html;
# set $no_cache 0;
access_log /home/main_domain/public_html/dev/subdomains/subdomain2/access.log;
error_log /home/main_domain/public_html/dev/subdomains/subdomain2/error.log;
location / {
try_files $uri $uri/ /index.php?$1;
# proxy_cache my_cache;
# proxy_pass http://main_domain2.com;
# proxy_cache_valid 200 302 60m;
# proxy_cache_valid 404 1m;
}
location ~* \favicon.ico$ {
expires 6m;
}
location ~* \.(js|css)$ { try_files $uri /index.php?$query_string; expires 1h; add_header Pragma "public"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; }
#avoid php readfile()
location ^~ /blog {
internal;
alias /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot/blog ;
access_log off; log_not_found off; expires max;
}
location ~ \.php$ {
try_files $uri =404;
# fastcgi_cache my_cache;
# fastcgi_cache_valid 200 60m; # Only cache 200 responses, cache for 60 minutes
# fastcgi_cache_methods GET HEAD; # Only GET and HEAD methods apply
# add_header X-Fastcgi-Cache $upstream_cache_status;
# fastcgi_cache_bypass $no_cache; # Don't pull from cache based on $no_cache
# fastcgi_no_cache $no_cache; # Don't save to cache based on $no_cache
# fastcgi_buffer_size 128k;
# fastcgi_buffers 256 4k;
# fastcgi_busy_buffers_size 256k;
# fastcgi_temp_file_write_size 256k;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/main_domain/public_html/dev/subdomains/subdomain2/app/webroot$fastcgi_script_name;
}
}
答案1
实际上,您只提供了 Nginx 配置的一小部分,但似乎混淆了 Nginx 的缓存选项。显示proxy_no_cache选项用于 Nginx 的 Web 代理功能(将请求转发到另一个 Web 服务器)。
对于本地托管的静态文件(例如图片、css、js...),请允许 Nginx 使用以下方式发送适当的缓存标头:到期选项。
对于 PHP 应用程序,您可以使用 Nginx 的 FastCGI 缓存。您可能知道,Nginx 会将请求转发到 PHP 守护程序(如 PHP-FPM)。整个 PHP 魔法都发生在这个 PHP-FPM 守护程序中,Nginx 只会获取最终响应并将其发送回客户端。
PHP 应用程序现在可以决定将缓存标头包含到此响应中。如果允许缓存(例如公共页面),PHP 可能会返回 Cache-Control 标头以允许缓存。
<?php
...
header('Cache-Control: public, max-age=3600');
...
?>
如果不允许缓存,PHP 可能会返回不同的 Cache-Control 标头来拒绝缓存:
<?php
...
header('Cache-Control: private, no-store, max-age=0');
...
?>
如果您的 PHP 应用程序能够发送正确的缓存标头,则可以使用以下配置使用 Nginx FastCGI 缓存:
fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=phpfpm:64m inactive=24h max_size=512M;
server {
listen 80;
server_name www.mysite.com;
root /var/www/xyz;
index index.php index.html;
# check for static files and deliver, for everything else use /index.php
location / {
try_files $uri $uri/ /index.php;
}
# set caching header for static files
location ~* \.(jpg|jpeg|gif|png|css|js|ico|svg|ttf)$ {
access_log off;
log_not_found off;
expires 30d;
}
# set caching header for asset files, don't exec index.php just show 404
location ^~ /assets/ {
try_files $uri =404;
access_log off;
log_not_found off;
expires 30d;
}
# PHP handler, allow FastCGI caching
location ~ \.php$ {
access_log /var/log/nginx/access.log combined;
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_cache phpfpm;
fastcgi_cache_use_stale updating error timeout invalid_header http_500;
}
}
如果您的 PHP 应用程序无法发送正确的缓存标头,您可以强制缓存或覆盖错误的缓存标头。请注意,这可能会导致将私人数据发布到公众手中!
结论
应该始终由 Web 应用程序(此处为 PHP 应用程序)定义要缓存哪些页面,哪些不缓存。使用 Web 服务器(Nginx、Apache 或其他)做出此决定就像使用防撞护栏从外部控制汽车一样。这很有效,但使用方向盘更智能。