8

我运行一个 nginx 服务器 + PHP webservices API。我使用 nginx 的 fastcgi_cache 来缓存所有 GET 请求,当某些资源被更新时,我会清除一个或多个相关的缓存资源。

我用来执行此操作的方法是计算我要清除的每个资源的 nginx 缓存文件名,然后删除该文件。在大多数情况下,这很好用。

但是,我发现有时候,即使缓存文件被删除,nginx 仍然会从缓存中返回数据。

选择要删除的正确缓存文件不是问题——作为我测试的一部分,我已经删除了整个缓存目录,nginx 仍然返回 HIT 响应

有谁知道为什么会发生这种情况?是否可能涉及另一个缓存?例如,操作系统是否正在向 nginx 返回缓存文件的缓存版本,所以 nginx 不知道它已被删除?

我在 CentOS 上运行它,并使用这个 nginx 配置(减去不相关的部分):

user nginx;

# Let nginx figure out the best value
worker_processes auto;

events {
    worker_connections  10240;
    multi_accept        on;
    use                 epoll;
}

# Maximum number of open files should be at least worker_connections * 2
worker_rlimit_nofile 40960;

# Enable regex JIT compiler
pcre_jit on;

http {

    # TCP optimisation
    sendfile        on;
    tcp_nodelay     on;
    tcp_nopush      on;

    # Configure keep alive
    keepalive_requests  1000;
    keepalive_timeout   120s 120s;

    # Configure SPDY
    spdy_headers_comp 2;

    # Configure global PHP cache
    fastcgi_cache_path /var/nginx/cache levels=1:2 keys_zone=xxx:100m inactive=24h;

    # Enable open file caching
    open_file_cache max=10000 inactive=120s;
    open_file_cache_valid 120s;
    open_file_cache_min_uses 5;
    open_file_cache_errors off;

    server {
        server_name xxx;
        listen 8080;

        # Send all dynamic content requests to the main app handler
        if (!-f $document_root$uri) {

            rewrite ^/(.+)    /index.php/$1         last;
            rewrite ^/        /index.php            last;
        }

        # Proxy PHP requests to php-fpm
        location ~ [^/]\.php(/|$) {

            # Enable caching
            fastcgi_cache xxx;

            # Only cache GET and HEAD responses
            fastcgi_cache_methods GET HEAD;

            # Caching is off by default, an can only be enabled using Cache-Control response headers
            fastcgi_cache_valid 0;

            # Allow only one identical request to be forwarded (others will get a stale response)
            fastcgi_cache_lock on;

            # Define conditions for which stale content will be returned
            fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503;

            # Define cache key to uniquely identify cached objects
            fastcgi_cache_key "$scheme$request_method$host$request_uri";

            # Add a header to response to indicate cache results
            add_header X-Cache $upstream_cache_status;

            # Configure standard server parameters
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            include fastcgi_params;

            # php-fpm config
            fastcgi_param SCRIPT_URL        $fastcgi_path_info;
            fastcgi_param PATH_INFO         $fastcgi_path_info;
            fastcgi_param SCRIPT_FILENAME   $document_root$fastcgi_script_name;
            fastcgi_param REQUEST_SCHEME    $scheme;
            fastcgi_param REMOTE_USER       $remote_user;

            # Read buffer sizes
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;

            # Keep connection open to enable keep-alive
            fastcgi_keep_conn on;

            # Proxy to PHP
            fastcgi_pass unix:/var/run/php-fpm/fpm.sock;
        }
    }
}

现在我看到了这个,open_file_cache 参数会影响缓存文件吗?

有任何想法吗?

4

1 回答 1

7

不,操作系统不缓存文件。

然而,这可能发生的原因是文件实际上并没有被完全删除,直到链接计数和打开文件的进程数都降到零。

unlink(2)手册页记录了诸如 之类的工具使用的系统调用rm,内容如下:

unlink () 函数从其目录中删除由 path 命名的链接,并减少链接引用的文件的链接计数。如果该减量将文件的链接计数减少到零,并且没有进程打开该文件,则与该文件关联的所有资源都将被回收。如果一个或多个进程在删除最后一个链接时打开了文件,则删除链接,但文件的删除会延迟,直到所有对它的引用都已关闭。

根据系统的不同,您实际上仍然可以完全恢复这些打开的文件而不会丢失任何数据,例如,请参阅https://unix.stackexchange.com/questions/61820/how-can-i-access-a-deleted-open -file-on-linux-output-of-a-running-crontab-task

因此,实际上,open_file_cache将有效地阻止您的删除对在其缓存中仍然具有相关文件描述符的进程产生任何影响。open_file_cache_valid如果删除后的紧急清除对您来说非常重要,您可能希望使用更短的时间。

于 2015-09-16T02:16:02.003 回答