Varnish (?) 中断文件下载

Pao*_*uto 3 varnish varnish-4

在 debian buster 服务器上,我有一个 apache2 Web 服务器,前面有 varnish 作为缓存,实际上 varnish 监听端口 80 并从监听端口 8080 的 apache 获取数据。

\n

也许自从从stretch升级后,文件下载不再完成。

\n

使用curl下载:

\n
$ wget -v -t 1 https://myserver.org/myfile.zip\n--2020-07-10 19:52:34--  https://myserver.org/myfile.zip\nResolving myserver.org (myserver.org)... w.x.y.z\nConnecting to myserver.org (myserver.org)|w.x.y.z|:443... connected.\nHTTP request sent, awaiting response... 200 OK\nLength: 333774113 (318M) [application/zip]\nSaving to: 'myfile.zip.13'\n\nmyfile.zip.13                                                         1%[=>    ]   4.43M  8.29MB/s    in 0.5s    \n\n2020-07-10 19:52:35 (8.29 MB/s) - Connection closed at byte 4649063. Giving up.\n
Run Code Online (Sandbox Code Playgroud)\n

每个请求的传输量都不同。

\n

这是此请求的清漆日志:

\n
*   << Request  >> 2104598   \n-   Begin          req 2104597 rxreq\n-   Timestamp      Start: 1594404000.669087 0.000000 0.000000\n-   Timestamp      Req: 1594404000.669087 0.000000 0.000000\n-   ReqStart       127.0.0.1 40966 a0\n-   ReqMethod      GET\n-   ReqURL         /myfile.zip\n-   ReqProtocol    HTTP/1.1\n-   ReqHeader      User-Agent: Wget/1.19.4 (linux-gnu)\n-   ReqHeader      Accept: */*\n-   ReqHeader      Accept-Encoding: identity\n-   ReqHeader      Host: myserver.org\n-   ReqHeader      X-SSL: 1\n-   ReqHeader      X-Forwarded-Proto: https\n-   ReqHeader      X-Forwarded-For: a.b.c.d\n-   ReqHeader      Connection: close\n-   ReqUnset       X-Forwarded-For: a.b.c.d\n-   ReqHeader      X-Forwarded-For: a.b.c.d, 127.0.0.1\n-   VCL_call       RECV\n-   ReqUnset       Accept-Encoding: identity\n-   VCL_return     hash\n-   VCL_call       HASH\n-   VCL_return     lookup\n-   VCL_call       MISS\n-   VCL_return     fetch\n-   Link           bereq 2104599 fetch\n-   Timestamp      Fetch: 1594404000.669596 0.000509 0.000509\n-   RespProtocol   HTTP/1.1\n-   RespStatus     200\n-   RespReason     OK\n-   RespHeader     Date: Fri, 10 Jul 2020 18:00:00 GMT\n-   RespHeader     Last-Modified: Sun, 28 Jun 2020 14:46:46 GMT\n-   RespHeader     ETag: "13e4fd21-5a92602e5bcc1"\n-   RespHeader     Content-Length: 333774113\n-   RespHeader     Content-Type: application/zip\n-   RespHeader     X-Varnish: 2104598\n-   RespHeader     Age: 0\n-   RespHeader     Via: 1.1 varnish (Varnish/6.1)\n-   VCL_call       DELIVER\n-   RespHeader     X-Cache: uncached\n-   RespUnset      Via: 1.1 varnish (Varnish/6.1)\n-   RespUnset      X-Varnish: 2104598\n-   VCL_return     deliver\n-   Timestamp      Process: 1594404000.669609 0.000521 0.000012\n-   RespHeader     Accept-Ranges: bytes\n-   RespHeader     Connection: close\n-   Timestamp      Resp: 1594404000.884468 0.215381 0.214859\n-   ReqAcct        237 0 237 260 4649063 4649323\n-   End\n
Run Code Online (Sandbox Code Playgroud)\n

这是后端交互(其他wget运行,在字节6291456处关闭):

\n
*   << BeReq    >> 2612416   \n-   Begin          bereq 2612415 fetch\n-   Timestamp      Start: 1594674394.093379 0.000000 0.000000\n-   BereqMethod    GET\n-   BereqURL       /myfile.zip\n-   BereqProtocol  HTTP/1.1\n-   BereqHeader    User-Agent: Wget/1.19.4 (linux-gnu)\n-   BereqHeader    Accept: */*\n-   BereqHeader    Host: myserver.org\n-   BereqHeader    X-SSL: 1\n-   BereqHeader    X-Forwarded-Proto: https\n-   BereqHeader    X-Forwarded-For: a.b.c.d, 127.0.0.1\n-   BereqHeader    Accept-Encoding: gzip\n-   BereqHeader    X-Varnish: 2612416\n-   VCL_call       BACKEND_FETCH\n-   VCL_return     fetch\n-   BackendOpen    28 default 127.0.0.1 8080 127.0.0.1 50218\n-   BackendStart   127.0.0.1 8080\n-   Timestamp      Bereq: 1594674394.093413 0.000034 0.000034\n-   Timestamp      Beresp: 1594674394.093710 0.000330 0.000297\n-   BerespProtocol HTTP/1.1\n-   BerespStatus   200\n-   BerespReason   OK\n-   BerespHeader   Date: Mon, 13 Jul 2020 21:06:34 GMT\n-   BerespHeader   Server: Apache\n-   BerespHeader   Last-Modified: Sun, 28 Jun 2020 14:46:46 GMT\n-   BerespHeader   ETag: "13e4fd21-5a92602e5bcc1"\n-   BerespHeader   Accept-Ranges: bytes\n-   BerespHeader   Content-Length: 333774113\n-   BerespHeader   Content-Type: application/zip\n-   TTL            RFC 120 10 0 1594674394 1594674394 1594674394 0 0 cacheable\n-   VCL_call       BACKEND_RESPONSE\n-   BerespUnset    Server: Apache\n-   TTL            VCL 1800 10 0 1594674394 cacheable\n-   TTL            VCL 1800 30 0 1594674394 cacheable\n-   VCL_return     deliver\n-   Filters        \n-   Storage        malloc s0\n-   Fetch_Body     3 length stream\n-   ExpKill        LRU_Cand p=0x7f97b4a358c0 f=0x0 r=1\n-   ExpKill        LRU x=2631322\n-   ExpKill        LRU_Cand p=0x7f97efa67980 f=0x0 r=1\n-   ExpKill        LRU x=2284258\n-   ExpKill        LRU_Cand p=0x7f97b4a6b1c0 f=0x0 r=1\n-   ExpKill        LRU x=2631334\n-   ExpKill        LRU_Cand p=0x7f97efa67a40 f=0x0 r=1\n-   ExpKill        LRU x=2284266\n-   ExpKill        LRU_Cand p=0x7f97efa67b00 f=0x0 r=1\n-   ExpKill        LRU x=2284269\n-   ExpKill        LRU_Cand p=0x7f97d484c780 f=0x0 r=1\n-   ExpKill        LRU x=1667855\n-   ExpKill        LRU_Cand p=0x7f97d9af1bc0 f=0x0 r=1\n-   ExpKill        LRU x=2950859\n-   ExpKill        LRU_Cand p=0x7f97e7886040 f=0x0 r=1\n-   ExpKill        LRU x=2472240\n-   ExpKill        LRU_Cand p=0x7f97d9af1c80 f=0x0 r=1\n-   ExpKill        LRU x=2950862\n-   ExpKill        LRU_Cand p=0x7f97d484e640 f=0x0 r=1\n-   ExpKill        LRU x=1667862\n-   ExpKill        LRU_Cand p=0x7f97d484eac0 f=0x0 r=1\n-   ExpKill        LRU x=1667865\n-   ExpKill        LRU_Cand p=0x7f97d9af1e00 f=0x0 r=1\n-   ExpKill        LRU x=2950865\n-   ExpKill        LRU_Cand p=0x7f97d48d2180 f=0x0 r=1\n-   ExpKill        LRU x=1667871\n-   ExpKill        LRU_Cand p=0x7f97d9af2040 f=0x0 r=1\n-   ExpKill        LRU x=2950871\n-   ExpKill        LRU_Cand p=0x7f97d9af2100 f=0x0 r=1\n-   ExpKill        LRU x=2950876\n-   ExpKill        LRU_Cand p=0x7f97b4b11000 f=0x0 r=1\n-   ExpKill        LRU x=2631343\n-   ExpKill        LRU_Cand p=0x7f97efa67bc0 f=0x0 r=1\n-   ExpKill        LRU x=2284275\n-   ExpKill        LRU_Cand p=0x7f97efa67c80 f=0x0 r=1\n-   ExpKill        LRU x=2284278\n-   ExpKill        LRU_Cand p=0x7f97d48d3b00 f=0x0 r=1\n-   ExpKill        LRU x=1667880\n-   ExpKill        LRU_Cand p=0x7f97e7886100 f=0x0 r=1\n-   ExpKill        LRU x=2472249\n-   ExpKill        LRU_Cand p=0x7f97d9a3d3c0 f=0x0 r=1\n-   ExpKill        LRU x=2950879\n-   ExpKill        LRU_Cand p=0x7f97d9a3d900 f=0x0 r=1\n-   ExpKill        LRU x=2950886\n-   ExpKill        LRU_Cand p=0x7f97d48d4040 f=0x0 r=1\n-   ExpKill        LRU x=1667895\n-   ExpKill        LRU_Cand p=0x7f97e79d1e80 f=0x0 r=1\n-   ExpKill        LRU x=2631367\n-   ExpKill        LRU_Cand p=0x7f97d6bf6780 f=0x0 r=1\n-   ExpKill        LRU x=1205206\n-   ExpKill        LRU_Cand p=0x7f97cbb3c2c0 f=0x0 r=1\n-   ExpKill        LRU x=2325555\n-   ExpKill        LRU_Cand p=0x7f97d6bf6840 f=0x0 r=1\n-   ExpKill        LRU x=1205217\n-   ExpKill        LRU_Cand p=0x7f97e7886340 f=0x0 r=1\n-   ExpKill        LRU x=2472273\n-   ExpKill        LRU_Cand p=0x7f97cbb3c380 f=0x0 r=1\n-   ExpKill        LRU x=2325569\n-   ExpKill        LRU_Cand p=0x7f97cbb3c440 f=0x0 r=1\n-   ExpKill        LRU x=2325572\n-   ExpKill        LRU_Cand p=0x7f97d6bf69c0 f=0x0 r=1\n-   ExpKill        LRU x=1205230\n-   ExpKill        LRU_Cand p=0x7f97e7886400 f=0x0 r=1\n-   ExpKill        LRU x=2472276\n-   ExpKill        LRU_Cand p=0x7f97d6bf6b40 f=0x0 r=1\n-   ExpKill        LRU x=1205239\n-   ExpKill        LRU_Cand p=0x7f97b4b11480 f=0x0 r=1\n-   ExpKill        LRU x=2631405\n-   ExpKill        LRU_Cand p=0x7f97b4b11540 f=0x0 r=1\n-   ExpKill        LRU x=2631410\n-   ExpKill        LRU_Cand p=0x7f97e7886640 f=0x0 r=1\n-   ExpKill        LRU x=2472294\n-   ExpKill        LRU_Cand p=0x7f97b4b116c0 f=0x0 r=1\n-   ExpKill        LRU x=2631416\n-   ExpKill        LRU_Cand p=0x7f97e7886700 f=0x0 r=1\n-   ExpKill        LRU x=2472299\n-   ExpKill        LRU_Cand p=0x7f97b4b11780 f=0x0 r=1\n-   ExpKill        LRU x=2631419\n-   ExpKill        LRU_Cand p=0x7f97e78867c0 f=0x0 r=1\n-   ExpKill        LRU x=2472302\n-   ExpKill        LRU_Cand p=0x7f97e7886880 f=0x0 r=1\n-   ExpKill        LRU x=2472305\n-   ExpKill        LRU_Cand p=0x7f97b4b11b40 f=0x0 r=1\n-   ExpKill        LRU x=2631428\n-   ExpKill        LRU_Cand p=0x7f97e7886940 f=0x0 r=1\n-   ExpKill        LRU x=2472308\n-   ExpKill        LRU_Cand p=0x7f97e7886ac0 f=0x0 r=1\n-   ExpKill        LRU x=2472314\n-   ExpKill        LRU_Cand p=0x7f97b4b12080 f=0x0 r=1\n-   ExpKill        LRU x=2631434\n-   ExpKill        LRU_Cand p=0x7f97d6bf6c00 f=0x0 r=1\n-   ExpKill        LRU x=1205267\n-   ExpKill        LRU_Cand p=0x7f97e7886b80 f=0x0 r=1\n-   ExpKill        LRU x=2472348\n-   ExpKill        LRU_Cand p=0x7f97d6bf6cc0 f=0x0 r=1\n-   ExpKill        LRU x=1205274\n-   ExpKill        LRU_Cand p=0x7f97b4b12200 f=0x0 r=1\n-   ExpKill        LRU x=2631441\n-   ExpKill        LRU_Cand p=0x7f97e7886c40 f=0x0 r=1\n-   ExpKill        LRU x=2472360\n-   ExpKill        LRU reached nuke_limit\n-   FetchError     Could not get storage\n-   BackendClose   28 default\n-   BereqAcct      244 0 244 230 10764288 10764518\n-   End            \n
Run Code Online (Sandbox Code Playgroud)\n

我无法理解发生了什么事...

\n

这是我的清漆的default.vcl:

\n
# Marker to tell the VCL compiler that this VCL has been adapted to the\n# new 4.0 format.\nvcl 4.0;\n\n# Default backend definition. Set this to point to your content server.\nbackend default {\n    .host = "127.0.0.1";\n    .port = "8080";\n}\n\n# access control list for "purge": open to only localhost and other local nodes\nacl purge {\n    "127.0.0.1";\n    "localhost";\n}\n\n# vcl_recv is called whenever a request is received \nsub vcl_recv {\n        # Serve objects up to 2 minutes past their expiry if the backend\n        # is slow to respond.\n        #set req.grace = 120s;\n        if (req.http.X-Forwarded-Proto !~ "https")\n        {\n          unset req.http.X-Forwarded-For;\n          set req.http.X-Forwarded-For = client.ip;\n        }\n        set req.backend_hint= default;\n\n        # This uses the ACL action called "purge". Basically if a request to\n        # PURGE the cache comes from anywhere other than localhost, ignore it.\n        if (req.method == "PURGE") \n            {\n                if (!client.ip ~ purge)\n                    {return(synth(405,"Not allowed."));}\n                #return(hash);}\n                return(purge);\n            }\n\n        # Pass any requests that Varnish does not understand straight to the backend.\n        if (req.method != "GET" && req.method != "HEAD" &&\n            req.method != "PUT" && req.method != "POST" &&\n            req.method != "TRACE" && req.method != "OPTIONS" &&\n            req.method != "DELETE") \n            {return(pipe);}     /* Non-RFC2616 or CONNECT which is weird. */\n\n        # Pass anything other than GET and HEAD directly.\n        if (req.method != "GET" && req.method != "HEAD")\n           {return(pass);}      /* We only deal with GET and HEAD by default */\n\n        # Pass requests from logged-in users directly.\n        #if (req.http.Authorization || req.http.Cookie)\n        #   {return(pass);}      /* Not cacheable by default */\n\n        # Pass any requests with the "If-None-Match" header directly.\n        if (req.http.If-None-Match)\n           {return(pass);}\n\n        # Force lookup if the request is a no-cache request from the client.\n        # DISATTIVO PERCH\xc3\x89 ban RICHIEDE UNA COMPARAZIONE\n        #if (req.http.Cache-Control ~ "no-cache")\n        #   {ban(req.url);}\n\n        # normalize Accept-Encoding to reduce vary\n        if (req.http.Accept-Encoding) {\n          if (req.http.User-Agent ~ "MSIE 6") {\n            unset req.http.Accept-Encoding;\n          } elsif (req.http.Accept-Encoding ~ "gzip") {\n            set req.http.Accept-Encoding = "gzip";\n          } elsif (req.http.Accept-Encoding ~ "deflate") {\n            set req.http.Accept-Encoding = "deflate";\n          } else {\n            unset req.http.Accept-Encoding;\n          }\n        }\n\n\n        # remove the cookies form static files in order to serve them from cache\n        if (req.url ~ "(?i)\\.(jpeg|jpg|png|gif|ico|webp|js|css|txt|pdf|gz|zip|lzma|bz2|tgz|tbz|html|htm)$") {\n            unset req.http.cookie;\n        }\n\n        # Do not cache HTTP authentication and HTTP Cookie\n        if (req.http.Authorization || req.http.Cookie) {\n            # Not cacheable by default\n            return (pass);\n        }\n\n        return(hash);\n        #return(pass);\n}\n\nsub vcl_pipe {\n        # Note that only the first request to the backend will have\n        # X-Forwarded-For set.  If you use X-Forwarded-For and want to\n        # have it set for all requests, make sure to have:\n        # set req.http.connection = "close";\n \n        # This is otherwise not necessary if you do not do any request rewriting.\n \n        set req.http.connection = "close";\n}\n\n# Called if the cache has a copy of the page.\nsub vcl_hit {\n        if (req.method == "PURGE") \n            {ban(req.url);\n            return(synth(200,"Purged"));}\n \n        if (!obj.ttl > 0s)\n           {return(pass);}\n}\n \n# Called if the cache does not have a copy of the page.\nsub vcl_miss {\n        if (req.method == "PURGE") \n           {return(synth(200,"Not in cache"));}\n}\n\n# Called after a document has been successfully retrieved from the backend.\nsub vcl_backend_response {\n \n    # Remove some headers we never want to see\n    unset beresp.http.Server;\n    unset beresp.http.X-Powered-By;\n\n    # For static content strip all backend cookies\n    if (bereq.url ~ "\\.(css|js|png|gif|jp(e?)g)|swf|ico") {\n        unset beresp.http.cookie;\n    }\n    # Don't store backend\n    if (bereq.url ~ "wp-(login|admin)" || bereq.url ~ "preview=true") {\n        set beresp.uncacheable = true;\n        set beresp.ttl = 30s;\n        return (deliver);\n    }\n\n\n    # don't cache response to posted requests or those with basic auth\n    if ( bereq.method == "POST" || bereq.http.Authorization ) {\n            set beresp.uncacheable = true;\n        set beresp.ttl = 120s;\n        return (deliver);\n        }\n\n        # don't cache search results\n    if ( bereq.url ~ "\\?s=" ){\n        set beresp.uncacheable = true;\n                set beresp.ttl = 120s;\n                return (deliver);\n    }\n\n    # only cache status ok\n    if ( beresp.status != 200 ) {\n        set beresp.uncacheable = true;\n                set beresp.ttl = 120s;\n                return (deliver);\n    }\n\n    # A TTL of 2h\n    set beresp.ttl = 30m;\n    # Define the default grace period to serve cached content\n    set beresp.grace = 30s;\n        return (deliver);\n}\n\nsub vcl_deliver {\n    if (obj.hits > 0) {\n        set resp.http.X-Cache = "cached";\n    } else {\n        set resp.http.x-Cache = "uncached";\n    }\n\n    # Remove some headers: PHP version\n    unset resp.http.X-Powered-By;\n\n    # Remove some headers: Apache version & OS\n    unset resp.http.Server;\n\n    # Remove some heanders: Varnish\n    unset resp.http.Via;\n    unset resp.http.X-Varnish;\n    \n    return(deliver);\n}\n\n#sub vcl_fetch {\n#   if (req.url ~ "^/piwik") {\n#       return(hit_for_pass);\n#   }\n#}\n
Run Code Online (Sandbox Code Playgroud)\n

Thi*_*ryn 7

根据后端varnishlog信息,我可以得出结论,您的存储空间不足。

这些是确认这一点的日志项:

-   ExpKill        LRU reached nuke_limit
-   FetchError     Could not get storage
Run Code Online (Sandbox Code Playgroud)

当缓存已满并且 Varnish 想要在缓存中存储另一个对象时,LRU(最近最少使用)机制就会启动。

这意味着它开始在缓存中查找最近最少使用的项目,并将它们从缓存中逐出。Varnish 会多次执行此操作,直到达到默认nuke_limit设置为50的值。

在这种情况下,Varnish将尝试删除最近最少使用的50个对象,以便将新对象放入缓存中。

我的假设是,50 个最近最少使用的对象的大小非常小,并且释放的空间与新对象的大小要求不匹配。

以下是您的一些选择:

  • nuke_limit使用运行时选项增加参数-p-p nuke_limit=100例如)
  • 对某些对象应用不同的TTL,以确保它们更快过期
  • 主动使部分缓存失效,以保证可用空间
  • 增加内存大小以避免这些问题
  • 使用Varnish Enterprise 并受益于海量存储引擎,该引擎始终在缓存中保持可用空间,并动态调整缓存大小。