니스 금지가 추가되었지만 오래된 개체가 반환됩니다.

Jan 08 2021

맵 박스 타일을 캐시하기 위해 타일 서버 앞에서 광택제를 사용하고 있습니다. 오래된 타일을 제거하기 위해 차단을 사용하여 캐시 된 많은 타일을 효과적으로 제거하려고했습니다. 내 문제는 varnish가 여전히 캐시 된 객체를 사용하고 (적어도 age응답에서 이것을 나타냄) 백엔드에 연결하지 않는다는 것입니다.

나는 먼저 http : //varnish/5/3/4.pbf를 요청한 다음 curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish또는 대안 으로 금지를 추가 한 varnishadm다음 ban obj.http.url ~ 5/3/4.pbf나중에 http : //varnish/5/3/4.pbf를 다시 요청합니다.

처음에 내 금지 목록이 비어 있습니다.

Present bans:
1610117471.434488     1 C

금지는 다음과 함께 성공적으로 추가됩니다. curl -X BAN -H 'X-Purge-Regex: 5/3/4.pbf' varnish

<!DOCTYPE html>
<html>
  <head>
    <title>200 Ban added</title>
  </head>
  <body>
    <h1>Error 200 Ban added</h1>
    <p>Ban added</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 8</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

금지 목록에 표시됩니다.

Present bans:
1610117369.028870     0 -  obj.http.url ~ 5/3/4.pbf
1610117307.220739     1 C  

http : //varnish/5/3/4.pbf를 다시 요청하면 금지 목록에 금지가 사용되었음을 나타냅니다.

Present bans:
1610117471.434488     1 -  obj.http.url ~ 5/3/4.pbf

그러나 응답의 나이는 0이 아닙니다. 왜냐하면 그것은 여전히 ​​첫 번째 요청의 객체이기 때문입니다.

잠시 후 금지가 제거됩니다.

Present bans:
1610117471.434488     1 C  

vcl_recv모습은 이렇지 만 오류는 다음과 같이 작동하지 않기 때문에 다른 곳에있을 수 있습니다 varnishadm.

sub vcl_recv {
    unset req.http.cookie;

    # Allowing PURGE from localhost
    if (req.method == "BAN"||req.method == "PURGE") {
                if (!client.ip ~ purge) {
                        return(synth(405,"Not allowed."));
                }
                if (req.method == "BAN") {
                    ban("obj.http.url ~ " + req.http.X-Purge-Regex);

                    # Throw a synthetic page so the
                    # request won't go to the backend.
                    return(synth(200, "Ban added"));
                }
                if (req.method == "PURGE") {
                    return (purge);
                }
        }
}

나는 또한 vcl_purgefrom 을 사용하려고했습니다.https://stackoverflow.com/a/61507014 그러나 이것은 금지 (?)에 도움이되지 않는 것 같습니다.

나는 X-Purge-Regex헤더를 사용하여 다음 과 같은 특수 문자를 이스케이프해야하는 것에 대해 걱정하지 않습니다.https://stackoverflow.com/a/38526921하지만 같은 금지 obj.http.url ~ 0는 작동하지 않습니다.

vcl 4.0과 함께 varnish 6.5를 사용하고 있습니다.

금지 요청

*   << Request  >> 54        
-   Begin          req 53 rxreq
-   Timestamp      Start: 1610121483.345437 0.000000 0.000000
-   Timestamp      Req: 1610121483.345437 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.168.48.2 50882 http
-   ReqMethod      BAN
-   ReqURL         /
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: varnish-volatile
-   ReqHeader      User-Agent: curl/7.64.0
-   ReqHeader      Accept: */*
-   ReqHeader      X-Purge-Regex: 0
-   ReqHeader      X-Forwarded-For: 192.168.48.2
-   VCL_call       RECV
-   VCL_acl        MATCH purge "importer"
-   VCL_return     synth
-   VCL_call       HASH
-   VCL_return     lookup
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     Ban added
-   RespHeader     Date: Fri, 08 Jan 2021 15:58:03 GMT
-   RespHeader     Server: Varnish
-   RespHeader     X-Varnish: 54
-   VCL_call       SYNTH
-   RespHeader     Content-Type: text/html; charset=utf-8
-   RespHeader     Retry-After: 5
-   VCL_return     deliver
-   Timestamp      Process: 1610121483.347281 0.001844 0.001844
-   RespHeader     Content-Length: 246
-   Storage        malloc Transient
-   Filters        
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1610121483.347557 0.002120 0.000276
-   ReqAcct        98 0 98 218 246 464
-   End            

차단 추가 후 GET

*   << Request  >> 32806     
-   Begin          req 32805 rxreq
-   Timestamp      Start: 1610121552.733872 0.000000 0.000000
-   Timestamp      Req: 1610121552.733872 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       192.168.48.1 55176 http
-   ReqMethod      GET
-   ReqURL         /public.snow_db/0/0/0.pbf
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Host: localhost:8090
-   ReqHeader      User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0
-   ReqHeader      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-   ReqHeader      Accept-Language: en-US,en;q=0.5
-   ReqHeader      Accept-Encoding: gzip, deflate
-   ReqHeader      DNT: 1
-   ReqHeader      Connection: keep-alive
-   ReqHeader      Upgrade-Insecure-Requests: 1
-   ReqHeader      Pragma: no-cache
-   ReqHeader      Cache-Control: no-cache
-   ReqHeader      X-Forwarded-For: 192.168.48.1
-   VCL_call       RECV
-   ReqUnset       Host: localhost:8090
-   ReqHeader      host: localhost:8090
-   VCL_return     hash
-   ReqUnset       Accept-Encoding: gzip, deflate
-   ReqHeader      Accept-Encoding: gzip
-   VCL_call       HASH
-   VCL_return     lookup
-   Hit            28 601789.331504 10.000000 0.000000
-   VCL_call       HIT
-   VCL_return     deliver
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespHeader     content-encoding: gzip
-   RespHeader     content-type: application/x-protobuf
-   RespHeader     date: Fri, 08 Jan 2021 15:09:02 GMT
-   RespHeader     Vary: Accept-Encoding
-   RespHeader     X-Varnish: 32806 28
-   RespHeader     Age: 3010
-   RespHeader     Via: 1.1 varnish (Varnish/6.5)
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1610121552.734070 0.000197 0.000197
-   Filters        
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Content-Length: 295
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1610121552.734217 0.000345 0.000147
-   ReqAcct        414 0 414 272 295 567
-   End  

문제 재현

버그를 재현하려면 :

  • git clone https://github.com/Baschdl/varnish-ban-setup.git && cd varnish-ban-setup
  • docker-compose up
  • http : // localhost : 8092 / 5 / 3 / 1.pbf를 엽니 다.
  • docker-compose exec varnish varnishadm ban obj.http.url ~ pbf
  • http : // localhost : 8092 / 5 / 3 / 1.pbf를 다시 열면 이전 개체가 나타납니다.

답변

2 ThijsFeryn Jan 09 2021 at 00:23

obj.http.url ~ 5/3/4.pbf귀하가 발행 하는 금지는 url응답 헤더와 일치합니다 .

기억하세요 : URL은 응답 헤더가 아니라 요청 헤더입니다. 당황 할 이유가 없으며, 당신이하는 일이 완벽하게 이해가되며, 소위 밴 루커 의 범위와 관련이 있습니다.

루커 금지

금지 럴커는 비동기 캐시에서 개체의 패턴을 제거하기 위해 금지에 대한 금지 목록과 일치하는 개체에 대한 금지를 처리하는 스레드입니다.

ban lurker는 요청 범위 내에서 작동하지 않지만 객체 범위 만 알고 있습니다.

요청 정보를 성공적으로 일치시키기 위해 요청 컨텍스트를 응답 헤더로 추가 할 수 있습니다. 그리고 그것은 당신이obj.http.url

그렇다면 금지가 작동하지 않는 이유는 무엇입니까?

금지가 작동하지 않는 이유는 obj.http.urlVCL 파일에 설정하지 않았기 때문 입니다. 결과적으로 밴 루커는 어떤 물체도 일치시킬 수 없습니다.

문제 해결 방법

해결책은 간단합니다. 아래 그림과 같이 백엔드 응답 컨텍스트에 누락 된 헤더를 설정합니다.

sub vcl_backend_response {
    set beresp.http.url = bereq.url;
    set beresp.http.host = bereq.http.host;
}

백엔드가 응답하면 객체가 캐시에 저장되기 직전에 누락 된 헤더를 설정할 수 있습니다.

그 후, 밴 루커는 밴 표현식을 올바른 개체에 일치시키고 캐시에서 제거 할 수 있습니다.

개체가 즉시 일치되지 않는다는 점을 잊지 마십시오. 개체는 ban_lurker_age기본적으로 1 분으로 설정된에 도달 할 때만 제거됩니다 .