如何处理由于缓存停机造成的播放框架异常(redis)

时间:2015-08-08 14:56:49

标签: caching playframework redis

我想在我的播放服务器中使用redis缓存进行内容缓存(播放版本2.3.9,scala版本2.11)

我有一个播放动作,我正在使用Play框架文档here中概述的缓存操作进行包装,即

 def action(input: String) = Cached.status(_ => "cachekey", 200, 43200) {
    Action {implicit request =>
...

redis的播放插件效果很好。但是我意识到我在系统中引入了一个新的失败点。

如果redis服务器不可用或发生故障,该操作将抛出一个硬异常。我希望这可以像缓存未命中一样,并且仍然优雅地将响应返回给用户而不进行缓存。

我试图在try / catch块中包装缓存的调用:

    def safeCache(key: String, ttl: Int)(f: => Result)(implicit app: Application) = {
    try {
      Cached.status(_ => key, 200, ttl) {
        Action { implicit request =>
          f
        }
      }
    } catch {
      case e: Throwable =>
        Logger.error(s"Could not retrieve cache key for $key due to ${e.getMessage}", e)
        NewRelic.noticeError(e)
        Action { implicit request =>
          f
        }
    }
   }

但异常实际上是从我的应用程序控件之外的iteratee抛出的,所以

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.util.Pool.getResource(Pool.java:42) ~[jedis-2.4.2.jar:na]
    at org.sedis.Pool.withJedisClient(sedis.scala:101) ~[sedis_2.11-1.2.2.jar:na]
    at com.typesafe.plugin.RedisPlugin$$anon$1.set_(RedisPlugin.scala:144) ~[play-plugins-redis_2.11-2.3.1.jar:2.3.1]
    at com.typesafe.plugin.RedisPlugin$$anon$1.set(RedisPlugin.scala:103) ~[play-plugins-redis_2.11-2.3.1.jar:2.3.1]
    at play.api.cache.Cache$.set(Cache.scala:61) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.cache.Cache$.set(Cache.scala:72) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.cache.Cached$$anonfun$play$api$cache$Cached$$handleResult$1.apply(Cached.scala:83) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.cache.Cached$$anonfun$play$api$cache$Cached$$handleResult$1.apply(Cached.scala:73) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at scala.PartialFunction$AndThen.applyOrElse(PartialFunction.scala:190) ~[scala-library-2.11.6.jar:na]
    at play.api.cache.Cached.play$api$cache$Cached$$handleResult(Cached.scala:88) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.cache.Cached$$anonfun$build$1$$anonfun$apply$6$$anonfun$apply$7.apply(Cached.scala:57) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.cache.Cached$$anonfun$build$1$$anonfun$apply$6$$anonfun$apply$7.apply(Cached.scala:57) ~[play-cache_2.11-2.3.9.jar:2.3.9]
    at play.api.libs.iteratee.Iteratee$$anonfun$map$1.apply(Iteratee.scala:471) ~[play-iteratees_2.11-2.3.9.jar:2.3.9]
    at play.api.libs.iteratee.Iteratee$$anonfun$map$1.apply(Iteratee.scala:471) ~[play-iteratees_2.11-2.3.9.jar:2.3.9]
    at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:495) ~[play-iteratees_2.11-2.3.9.jar:2.3.9]
    at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:495) ~[play-iteratees_2.11-2.3.9.jar:2.3.9]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) [scala-library-2.11.6.jar:na]

是否有推荐的模式将这种redis缓存合并到播放框架服务器中,同时使用新的依赖关系优雅地处理潜在的停机时间?

0 个答案:

没有答案