英文:
Caffeine cache in Play Framework doesn't return cached responses
问题
我正在使用Caffeine缓存实现与我的Java Play Framework作业一起,用于缓存外部的HTTP请求,尽管缓存正在运行,但每次我的服务仍然会命中外部服务器,而不是从缓存中返回值。我在日志中看到,记录的密钥始终是相同的。
因此,我注意到freshnessLifetime
没有设置,这可能意味着缓存会立即过期。但我仍然不知道如何在配置中设置它。
我没有更改我的Java代码,我找不到任何示例,是否需要这样做,或者我只需要为所有外部请求都配置一个缓存。
对于这个问题,我会感激任何帮助。
我的build.sbt
包含:
libraryDependencies += ws
libraryDependencies += caffeine
我的reference.conf
包含:
# Configuration settings for JSR 107 Cache for Play WS.
play.ws.cache {
enabled = true
heuristics.enabled = false
name = "play-ws-cache"
}
我的application.conf
包含:
# source https://github.com/ben-manes/caffeine/blob/master/jcache/src/main/resources/reference.conf
caffeine.jcache {
# A named cache is configured by nesting a new definition under the caffeine.jcache namespace. The
# per-cache configuration is overlaid on top of the default configuration.
play-ws-cache {
read-through {
# If enabled, the entry is loaded automatically on a cache miss
enabled = true
}
# The eviction policy for automatically removing entries from the cache
policy {
# The expiration threshold before lazily evicting an entry. This single threshold is reset on
# every operation where a duration is specified. As expected by the specification, if an entry
# expires but is not accessed and no resource constraints force eviction, then the expired
# entry remains in place.
lazy-expiration {
# The duration before a read of an entry is considered expired. If set to 0 then the entry
# is considered immediately expired. May be a time duration, null to indicate no change, or
# "eternal" to indicate no expiration.
access = 5m
}
# The expiration thresholds before eagerly evicting an entry. These settings correspond to the
# expiration supported natively by Caffeine where expired entries are collected during
# maintenance operations.
eager-expiration {
# Specifies that each entry should be automatically removed from the cache once a fixed
# duration has elapsed after the entry's creation, the most recent replacement of its value,
# or its last read. Access time is reset by all cache read and write operation. This setting
# cannot be combined with the variable configuration.
after-access = 5m
}
# The maximum bounding of the cache based upon its logical size
maximum {
# The maximum number of entries that can be held by the cache. This setting cannot be
# combined with the weight configuration.
size = 10000
}
}
}
}
在日志中我看到这些内容:
[debug] - restclient.BaseRestClient - 执行GET请求,URL为http://localhost:9001/entities/v2/867386732
[trace] - p.a.l.w.a.c.CachingAsyncHttpClient - 执行:请求 = Request(GET http://localhost:9001/entities/v2/867386732),处理程序 = AsyncHandler(play.libs.ws.ahc.StandaloneAhcWSClient$ResponseAsyncCompletionHandler@65b0b233),未来 = null
[debug] - p.a.libs.ws.ahc.cache.AhcHttpCache - 获取:键 = GET http://localhost:9001/entities/v2/867386732
...
(此处省略了大量日志内容)
如果需要更多翻译或解释,请告诉我。
英文:
I'm using Caffeine cache implementation with my java Play Framework job to cache outgoing http requests, and I see that in spite of the fact that the cache is up and running, my service still hit the external server every time instead of returning the value from the cache.
And I see that the key logged in the logs is always the same.
So I see freshnessLifetime
is not set, so it might mean that the cache expires immediately. but I still don't know how to set it in the config
I have not changed my java code and I cannot find any examples if I need to do that, or I'm only supposed to have a config for cache working for all outgoing requests.
I would appreciate any help with this
My build.sbt
contains:
libraryDependencies += ws
libraryDependencies += caffeine
My reference.conf
contains:
# Configuration settings for JSR 107 Cache for Play WS.
play.ws.cache {
enabled = true
heuristics.enabled = false
name = "play-ws-cache"
}
My application.conf
contains:
# source https://github.com/ben-manes/caffeine/blob/master/jcache/src/main/resources/reference.conf
caffeine.jcache {
# A named cache is configured by nesting a new definition under the caffeine.jcache namespace. The
# per-cache configuration is overlaid on top of the default configuration.
play-ws-cache {
read-through {
# If enabled, the entry is loaded automatically on a cache miss
enabled = true
}
# The eviction policy for automatically removing entries from the cache
policy {
# The expiration threshold before lazily evicting an entry. This single threshold is reset on
# every operation where a duration is specified. As expected by the specification, if an entry
# expires but is not accessed and no resource constraints force eviction, then the expired
# entry remains in place.
lazy-expiration {
# The duration before a read of an entry is considered expired. If set to 0 then the entry
# is considered immediately expired. May be a time duration, null to indicate no change, or
# "eternal" to indicate no expiration.
access = 5m
}
# The expiration thresholds before eagerly evicting an entry. These settings correspond to the
# expiration supported natively by Caffeine where expired entries are collected during
# maintenance operations.
eager-expiration {
# Specifies that each entry should be automatically removed from the cache once a fixed
# duration has elapsed after the entry's creation, the most recent replacement of its value,
# or its last read. Access time is reset by all cache read and write operation. This setting
# cannot be combined with the variable configuration.
after-access = 5m
}
# The maximum bounding of the cache based upon its logical size
maximum {
# The maximum number of entries that can be held by the cache. This setting cannot be
# combined with the weight configuration.
size = 10000
}
}
}
}
I see in the logs this:
> [debug] - restclient.BaseRestClient - Executing GET with url
> http://localhost:9001/entities/v2/867386732 [trace] -
> p.a.l.w.a.c.CachingAsyncHttpClient - execute: request = Request(GET
> http://localhost:9001/entities/v2/867386732), handler =
> AsyncHandler(play.libs.ws.ahc.StandaloneAhcWSClient$ResponseAsyncCompletionHandler@65b0b233),
> future = null [debug] - p.a.libs.ws.ahc.cache.AhcHttpCache - get: key
> = GET http://localhost:9001/entities/v2/867386732 [debug] - p.a.l.w.a.c.CachingAsyncHttpClient - execute GET
> http://localhost:9001/entities/v2/867386732: results =
> List(ResponseEntry(CacheableResponse(status =
> CacheableHttpResponseStatus(code = 200, text = OK), headers =
> DefaultHttpHeaders[Referrer-Policy: origin-when-cross-origin,
> strict-origin-when-cross-origin, X-Frame-Options: DENY,
> X-XSS-Protection: 1; mode=block, X-Content-Type-Options: nosniff,
> X-Permitted-Cross-Domain-Policies: master-only, Date: Thu, 01 Oct 2020
> 17:44:08 GMT, Content-Type: application/json, Content-Length: 2144],
> bodyParts size =
> 1),GET,Map(),Some(2020-10-02T10:44:08.760450-07:00[America/Los_Angeles])))
> [trace] - c.t.c.ResponseSelectionCalculator - findMatchingResponse:
> request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> responses =
> List(StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map()))
> [debug] - p.a.l.w.a.c.CachingAsyncHttpClient - execute GET
> http://localhost:9001/entities/v2/867386732: selected from cache:
> ResponseEntry(CacheableResponse(status =
> CacheableHttpResponseStatus(code = 200, text = OK), headers =
> DefaultHttpHeaders[Referrer-Policy: origin-when-cross-origin,
> strict-origin-when-cross-origin, X-Frame-Options: DENY,
> X-XSS-Protection: 1; mode=block, X-Content-Type-Options: nosniff,
> X-Permitted-Cross-Domain-Policies: master-only, Date: Thu, 01 Oct 2020
> 17:44:08 GMT, Content-Type: application/json, Content-Length: 2144],
> bodyParts size =
> 1),GET,Map(),Some(2020-10-02T10:44:08.760450-07:00[America/Los_Angeles]))
> [trace] - c.t.c.CurrentAgeCalculator - calculateCurrentAge(headers:
> TreeMap(Date -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type ->
> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)), now:
> 2020-10-01T17:44:38.690992Z[GMT], requestTime:
> 2020-10-01T17:44:38.690274Z[GMT], responseTime:
> 2020-10-01T17:44:38.690981Z[GMT]) [trace] - c.t.c.CurrentAgeCalculator
> - calculateCurrentAge: currentAge = PT30S [debug] - c.t.c.ResponseServingCalculator - serveResponse: response found for
> 'GET http://localhost:9001/entities/v2/867386732', age = 30 [trace] -
> c.t.c.ResponseServingCalculator - noCacheFound: request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> response =
> StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map())
> [trace] - c.t.c.ResponseServingCalculator - isCachedResponseFresh:
> request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> response =
> StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map())
> [trace] - c.t.c.FreshnessCalculator - calculateFreshnessLifetime:
> [debug] - c.t.c.FreshnessCalculator - calculateFreshnessLifetime:
> freshnessLifetime = None [debug] - c.t.c.FreshnessCalculator -
> calculateFreshnessLifetime: result = PT0S [debug] -
> c.t.c.ResponseServingCalculator - isCachedResponseFresh:
> freshnessLifetime = PT0S, currentAge = PT30S [debug] -
> c.t.c.ResponseServingCalculator - isCachedResponseFresh:
> freshnessLifetime = PT0S, currentAge = PT30S [trace] -
> c.t.c.ResponseServingCalculator - isStaleResponseProhibited: request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> response =
> StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map())
> [trace] - c.t.c.ResponseServingCalculator - isStaleResponseAllowed:
> PT30S, request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> response =
> StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map())
> [debug] - c.t.c.ResponseServingCalculator - isStaleResponseAllowed:
> stale response not allowed [trace] - c.t.c.ResponseServingCalculator -
> canServeStaleAndRevalidate: response =
> StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:08 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only)),GET,Map())
> [trace] - c.t.c.FreshnessCalculator - calculateFreshnessLifetime:
> [debug] - c.t.c.FreshnessCalculator - calculateFreshnessLifetime:
> freshnessLifetime = None [debug] - c.t.c.FreshnessCalculator -
> calculateFreshnessLifetime: result = PT0S [trace] -
> c.t.c.FreshnessCalculator - calculateFreshnessLifetime: [debug] -
> c.t.c.FreshnessCalculator - calculateFreshnessLifetime:
> freshnessLifetime = None [debug] - c.t.c.FreshnessCalculator -
> calculateFreshnessLifetime: result = PT0S [debug] -
> p.a.l.w.a.c.CachingAsyncHttpClient - serveResponse GET
> http://localhost:9001/entities/v2/867386732: Response is stale, and
> stale response is not allowed -- revalidate with staleIfError = false
> [trace] - p.a.l.w.a.c.CachingAsyncHttpClient - buildValidationRequest:
> Request(GET http://localhost:9001/entities/v2/867386732), response =
> CacheableResponse(status = CacheableHttpResponseStatus(code = 200,
> text = OK), headers = DefaultHttpHeaders[Referrer-Policy:
> origin-when-cross-origin, strict-origin-when-cross-origin,
> X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block,
> X-Content-Type-Options: nosniff, X-Permitted-Cross-Domain-Policies:
> master-only, Date: Thu, 01 Oct 2020 17:44:08 GMT, Content-Type:
> application/json, Content-Length: 2144], bodyParts size = 1) [debug] -
> p.s.a.o.a.n.r.NettyRequestSender - Using pooled Channel '[id:
> 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001]' for
> 'GET' to 'http://localhost:9001/entities/v2/867386732' [debug] -
> p.s.a.o.a.n.r.NettyRequestSender - Using open Channel [id: 0x1fac35f7,
> L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001] for GET
> '/entities/v2/867386732' [trace] - p.s.a.i.n.h.logging.LoggingHandler
> - [id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001] WRITE: 107B
>
>
> [debug] - p.s.a.o.a.netty.handler.HttpHandler -
>
> Request DefaultFullHttpRequest(decodeResult: success, version:
> HTTP/1.1, content: EmptyByteBufBE) GET /entities/v2/867386732 HTTP/1.1
> host: localhost:9001 accept: / user-agent: AHC/2.1
>
> Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
> HTTP/1.1 200 OK Referrer-Policy: origin-when-cross-origin,
> strict-origin-when-cross-origin X-Frame-Options: DENY
> X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff
> X-Permitted-Cross-Domain-Policies: master-only Date: Thu, 01 Oct 2020
> 17:44:38 GMT Content-Type: application/json Content-Length: 2144
>
> [debug] - p.s.a.o.a.n.channel.ChannelManager - Adding key:
> http://localhost:9001 for channel [id: 0x1fac35f7, L:/127.0.0.1:49899
> - R:localhost/127.0.0.1:9001] [trace] - p.a.l.w.a.cache.AsyncCachingHandler - onCompleted: this =
> CacheAsyncHandler(key = GET
> http://localhost:9001/entities/v2/867386732, requestTime =
> 2020-10-01T17:44:38.692247Z[GMT], builder =
> play.api.libs.ws.ahc.cache.CacheableResponseBuilder@492a840f,
> asyncHandler =
> AsyncHandler(play.libs.ws.ahc.StandaloneAhcWSClient$ResponseAsyncCompletionHandler@65b0b233)})
> [debug] - p.a.l.w.a.cache.AsyncCachingHandler - onCompleted: response
> = CacheableResponse(status = CacheableHttpResponseStatus(code = 200, text = OK), headers = DefaultHttpHeaders[Referrer-Policy:
> origin-when-cross-origin, strict-origin-when-cross-origin,
> X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block,
> X-Content-Type-Options: nosniff, X-Permitted-Cross-Domain-Policies:
> master-only, Date: Thu, 01 Oct 2020 17:44:38 GMT, Content-Type:
> application/json, Content-Length: 2144], bodyParts size = 1) [trace] -
> p.a.libs.ws.ahc.cache.AhcHttpCache - invalidate: request = Request(GET
> http://localhost:9001/entities/v2/867386732), response =
> CacheableResponse(status = CacheableHttpResponseStatus(code = 200,
> text = OK), headers = DefaultHttpHeaders[Referrer-Policy:
> origin-when-cross-origin, strict-origin-when-cross-origin,
> X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block,
> X-Content-Type-Options: nosniff, X-Permitted-Cross-Domain-Policies:
> master-only, Date: Thu, 01 Oct 2020 17:44:38 GMT, Content-Type:
> application/json, Content-Length: 2144], bodyParts size = 1) [debug] -
> p.a.l.w.a.cache.AsyncCachingHandler - processFullResponse:
> fullResponse = CacheableResponse(status =
> CacheableHttpResponseStatus(code = 200, text = OK), headers =
> DefaultHttpHeaders[Referrer-Policy: origin-when-cross-origin,
> strict-origin-when-cross-origin, X-Frame-Options: DENY,
> X-XSS-Protection: 1; mode=block, X-Content-Type-Options: nosniff,
> X-Permitted-Cross-Domain-Policies: master-only, Date: Thu, 01 Oct 2020
> 17:44:38 GMT, Content-Type: application/json, Content-Length: 2144],
> bodyParts size = 1) [trace] - c.t.c.ResponseCachingCalculator -
> isCacheable: request:
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> response =
> OriginResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:38 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only))) [trace] -
> c.t.c.ResponseCachingCalculator - responseIsCacheable: response =
> OriginResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(Date
> -> List(Thu, 01 Oct 2020 17:44:38 GMT), Content-Type -> List(application/json), Content-Length -> List(2144), Referrer-Policy
> -> List(origin-when-cross-origin, strict-origin-when-cross-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1;
> mode=block), X-Content-Type-Options -> List(nosniff),
> X-Permitted-Cross-Domain-Policies -> List(master-only))) [trace] -
> c.t.c.ResponseCachingCalculator - isCacheable: result =
> DoCacheResponse(Response status code 200 is cacheable by default)
> [debug] - p.a.l.w.a.cache.AsyncCachingHandler - isCacheable: DO CACHE,
> because Response status code 200 is cacheable by default [debug] -
> p.a.libs.ws.ahc.cache.AhcHttpCache - cacheResponse: response =
> CacheableResponse(status = CacheableHttpResponseStatus(code = 200,
> text = OK), headers = DefaultHttpHeaders[Referrer-Policy:
> origin-when-cross-origin, strict-origin-when-cross-origin,
> X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block,
> X-Content-Type-Options: nosniff, X-Permitted-Cross-Domain-Policies:
> master-only, Date: Thu, 01 Oct 2020 17:44:38 GMT, Content-Type:
> application/json, Content-Length: 2144], bodyParts size = 1) [debug] -
> p.a.libs.ws.ahc.cache.AhcHttpCache - cacheResponse: strippedResponse =
> CacheableResponse(status = CacheableHttpResponseStatus(code = 200,
> text = OK), headers = DefaultHttpHeaders[Referrer-Policy:
> origin-when-cross-origin, strict-origin-when-cross-origin,
> X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block,
> X-Content-Type-Options: nosniff, X-Permitted-Cross-Domain-Policies:
> master-only, Date: Thu, 01 Oct 2020 17:44:38 GMT, Content-Type:
> application/json, Content-Length: 2144], bodyParts size = 1) [trace] -
> c.t.c.SecondaryKeyCalculator - calculate: request =
> CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()),
> responseHeaders = TreeMap(Date -> List(Thu, 01 Oct 2020 17:44:38 GMT),
> Content-Type -> List(application/json), Content-Length -> List(2144),
> Referrer-Policy -> List(origin-when-cross-origin,
> strict-origin-when-cross-origin), X-Frame-Options -> List(DENY),
> X-XSS-Protection -> List(1; mode=block), X-Content-Type-Options ->
> List(nosniff), X-Permitted-Cross-Domain-Policies -> List(master-only))
> [debug] - p.a.libs.ws.ahc.cache.AhcHttpCache - put: key = GET
> http://localhost:9001/entities/v2/867386732, entry =
> ResponseEntry(CacheableResponse(status =
> CacheableHttpResponseStatus(code = 200, text = OK), headers =
> DefaultHttpHeaders[Referrer-Policy: origin-when-cross-origin,
> strict-origin-when-cross-origin, X-Frame-Options: DENY,
> X-XSS-Protection: 1; mode=block, X-Content-Type-Options: nosniff,
> X-Permitted-Cross-Domain-Policies: master-only, Date: Thu, 01 Oct 2020
> 17:44:38 GMT, Content-Type: application/json, Content-Length: 2144],
> bodyParts size =
> 1),GET,Map(),Some(2020-10-02T10:44:38.771750-07:00[America/Los_Angeles]))
> [debug] - restclient.BaseRestClient - Response status [200] for url
> [http://localhost:9001/entities/v2/867386732] [trace] -
> p.s.a.i.n.h.logging.LoggingHandler - [id: 0x1fac35f7,
> L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001] READ COMPLETE [trace]
> - p.a.l.w.ahc.cache.CacheableResponse - getResponseBody:
答案1
得分: 0
我实际上找到了它是如何工作的。缓存不应该像 Redis 或 Memcached 这样的独立服务一样管理其生存周期,而是像浏览器一样,并且由 HTTP 响应中的头部进行管理。
在这里:https://github.com/playframework/cachecontrol/blob/e4694aa0665e2ccc5030ae1cf1d0b15ad5b98471/src/main/scala/com/typesafe/play/cachecontrol/FreshnessCalculator.scala#L42
因此,对于我来说解决方案是更改服务器,使其提供正确的头部:Cache-Control "max-age=3600, public"
。
英文:
I actually found how it works. The cache is not supposed to manage the lifetime like it does a separate service like Redis or Memcached but instead it acts like a browser does and is managed by the headers in HTTP response.
Here: https://github.com/playframework/cachecontrol/blob/e4694aa0665e2ccc5030ae1cf1d0b15ad5b98471/src/main/scala/com/typesafe/play/cachecontrol/FreshnessCalculator.scala#L42
So the solution for me was to change the server so it serves correct header: Cache-Control "max-age=3600, public"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论