无法使用 nginx 缓存处理用户登录会话

无法使用 nginx 缓存处理用户登录会话

我们在用户登录会话方面遇到了问题,这些问题是由于 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 或其他)做出此决定就像使用防撞护栏从外部控制汽车一样​​。这很有效,但使用方向盘更智能。

相关内容