0

我在我的 java Play Framework 作业中使用 Caffeine 缓存实现来缓存传出的 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
      }
    }
  }
}

我在日志中看到:

[调试] - restclient.BaseRestClient - 使用 url http://localhost:9001/entities/v2/867386732 [trace] - palwacCachingAsyncHttpClient - 执行:request = Request(GET http://localhost:9001/entities/v2/ 867386732),handler = AsyncHandler(play.libs.ws.ahc.StandaloneAhcWSClient$ResponseAsyncCompletionHandler@65b0b233),future = null [debug] - palibs.ws.ahc.cache.AhcHttpCache - get: key = GET http://localhost: 9001/entities/v2/867386732 [调试] - palwacCachingAsyncHttpClient - 执行 GET http://localhost:9001/entities/v2/867386732: 结果 = 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-类型选项: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] - ctcResponseSelectionCalculator - 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 -政策->List(master-only)),GET,Map())) [debug] - palwacCachingAsyncHttpClient - 执行 GET http://localhost:9001/entities/v2/867386732:从缓存中选择: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] - ctcCurrentAgeCalculator - calculateCurrentAge(headers :TreeMap(日期 -> 列表(星期四,2020 年 10 月 1 日 17:44:08 GMT),内容类型 -> 列表(应用程序/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)),现在:2020 -10-01T17:44:38.690992Z[GMT], requestTime: 2020-10-01T17:44:38.690274Z[GMT], responseTime: 2020-10-01T17:44:38.690981Z[GMT]) [trace] - ctcCurrentAgeCalculator2020-10-01T17:44:38.690981Z[GMT]) [trace] - ctcCurrentAgeCalculator2020-10-01T17:44:38.690981Z[GMT]) [trace] - ctcCurrentAgeCalculator

  • calculateCurrentAge: currentAge = PT30S [debug] - ctcResponseServingCalculator - serveResponse: 为 'GET http://localhost:9001/entities/v2/867386732' 找到响应,年龄 = 30 [trace] - ctcResponseServingCalculator - 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] - ctcResponseServingCalculator - isCachedResponseFresh: request = CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()), response = StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap (日期 -> 列表(星期四,2020 年 10 月 1 日 17:44:08 GMT),内容类型 -> 列表(应用程序/json),内容长度 -> 列表(2144),推荐人策略 -> 列表(来源- 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] - ctcFreshnessCalculator - calculateFreshnessLifetime: [debug] - ctcFreshnessCalculator - calculateFreshnessLifetime: freshnessLifetime = None [调试] - ctcFreshnessCalculator - calculateFreshnessLifetime:结果 = PT0S [debug] - ctcResponseServingCalculator - isCachedResponseFresh:freshnessLifetime = PT0S,currentAge = PT30S [debug] - ctcResponseServingCalculator - isCachedResponseFresh:freshnessLifetime = PT0S,currentAge = PT30S [trace] - ctcResponseServingCalculator - 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),内容类型 -> 列表(应用程序/json),内容长度 -> 列表(2144),推荐人策略 -> 列表(起源时交叉起源,严格起源时交叉-origin), X-Frame-Options -> List(DENY), X-XSS-Protection -> List(1; mode=block), X-Content-Type-Options -> List(nosniff), X-Permitted-跨域策略 ->List(master-only)),GET,Map()) [trace] - ctcResponseServingCalculator - isStaleResponseAllowed: PT30S, request = CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()), response = StoredResponse(http://localhost:9001/entities/v2/867386732,200,TreeMap(日期 -> 列表(周四,2020 年 10 月 1 日 17:44:08 GMT),内容类型 -> 列表(应用程序/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] - ctcResponseServingCalculator - isStaleResponseAllowed:不允许过时的响应 [trace] - ctcResponseServingCalculator - 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] - ctcFreshnessCalculator - calculateFreshnessLifetime: [debug] - ctcFreshnessCalculator - calculateFreshnessLifetime: freshnessLifetime = None [debug] - ctcFreshnessCalculator - calculateFreshnessLifetime: result = PT0S [trace] - ctcFreshnessCalculator - calculateFreshnessLifetime: [debug] - ctcFreshnessCalculator - calculateFresh :freshnessLifetime = None [debug] - ctcFreshnessCalculator - calculateFreshnessLifetime: result = PT0S [debug] - palwacCachingAsyncHttpClient - serveResponse GET http://localhost:9001/entities/v2/867386732:响应过时,并且不允许过时的响应 - 重新验证staleIfError = false [trace] - palwacCachingAsyncHttpClient - 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,日期:星期四,2020 年 10 月 1 日 17:44:08 GMT,内容类型:application/json,内容长度:2144],bodyParts 大小 = 1) [debug] - psaoanrNettyRequestSender - 使用池化通道 '[id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001]' 用于 'GET' 到 'http ://localhost:9001/entities/v2/867386732' [debug] - psaoanrNettyRequestSender - 使用开放通道 [id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001] 获取 '/ entity/v2/867386732' [trace] - psainhlogging.LoggingHandler/entities/v2/867386732' [trace] - psainhlogging.LoggingHandler/entities/v2/867386732' [trace] - psainhlogging.LoggingHandler
  • [id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1:9001] 写:107B

[调试] - psoanetty.handler.HttpHandler -

请求 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

响应 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-防护: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

[调试] - psaoanchannel.ChannelManager - 为通道添加密钥:http://localhost:9001 [id: 0x1fac35f7, L:/127.0.0.1:49899

  • 严格起源时跨起源,X-Frame-Options:拒绝,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] - ctcResponseCachingCalculator - 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-XSS-防护: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] - ctcSecondaryKeyCalculator - 计算:request = CacheRequest(http://localhost:9001/entities/v2/867386732,GET,TreeMap()), responseHeaders = TreeMap(Date -> 列表(周四,2020 年 10 月 1 日 17:44:38 GMT),内容类型 -> 列表(应用程序/json),内容长度 -> 列表(2144),推荐人策略 -> 列表(来源时间- 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] - palibs.ws.ahc.cache.AhcHttpCache - put: key = GET http://localhost: 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 - 响应状态 [200] for url [http://localhost:9001/entities/v2/867386732] [trace] - psainhlogging.LoggingHandler - [id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1 :9001]读取完成[跟踪] 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 - 响应状态 [200] for url [http://localhost:9001/entities/v2/867386732] [trace] - psainhlogging.LoggingHandler - [id: 0x1fac35f7, L:/127.0.0.1:49899 - R:localhost/127.0.0.1 :9001]读取完成[跟踪]
  • palwahc.cache.CacheableResponse - getResponseBody:
4

1 回答 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"

于 2020-10-02T00:51:03.000 回答