4

我有一个持久连接池(Memcached 客户端)。数据正在缓存在 memcached 服务器中。如果在重新启动 memcached 服务器后,我尝试使用客户端从池中获取缓存数据,则会出现以下异常:

java.util.concurrent.ExecutionException: java.lang.RuntimeException: Cancelled
    at net.spy.memcached.MemcachedClient$OperationFuture.get(MemcachedClient.java:1662)
    at net.spy.memcached.MemcachedClient$GetFuture.get(MemcachedClient.java:1708)
    at com.eos.gds.cache.CacheClient.get(CacheClient.java:49)

当我尝试获取缓存数据时,我仅在重新启动后第一次收到此异常。我做了很多搜索。但无法找到造成这种情况的确切原因。

4

5 回答 5

4

Spymemcached 有一堆内部队列,这些操作在实际发送到 memcached 之前被放入其中。这里发生的情况是您执行了一个操作,然后在通过网络发送该操作或从 memcached 接收到响应之前,Spymemcached 意识到连接已丢失。结果,Spymemcached 取消了所有运行中的操作,然后重新建立连接。

当您在 Future 上调用 get() 时,由于 Spymemcached 取消了操作,因此引发了异常。我建议在这里做的是捕获您使用 Spymemcached 执行的每个单独操作的所有异常,然后根据错误重试操作,或者只是忘记它。例如,如果它是一个 get 并且您的 memcached 服务器集群出现故障,那么您可能会忘记它,因为缓存将为空,但您可能想要重试一组。

于 2011-11-09T17:47:16.760 回答
1

我遇到了完全相同的问题并通过处理异常来解决它直到成功

while(true){
 try{
  memcacheclient.get(key);
  break;
 }
 catch(java.util.concurrent.CancellationException e ){
  log.info("cache cancelled");
 }
}
于 2014-09-23T04:50:20.813 回答
1

为每个新客户端运行一次 MemcachedClient.getStats(),这将解决取消问题。

于 2017-04-27T20:50:59.147 回答
0

我遇到过同样的问题。我正在使用 Spymemcached 客户端连接 Memcache 服务器。

我发现这个

应该是连接问题。

参考:https ://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/internal/OperationFuture.java

于 2017-06-09T07:19:53.283 回答
0

几天来一直在寻找解决方案。发帖以防它帮助别人。

我们的 ServletContextListener 实现在 contextInitialized 上获得了一个新的 MemcachedClient(...),然后在 contextDestroyed 上调用 MemacachedClient 方法 shutdown()。在我发送的第一个请求上,我总是会收到 CancellationException 或 ExecutionException。(错误消息暗示了两者,但 ExecutionException 是我能够捕捉到的。)

解决方法:从shutdown()切换到shutdown(1, TimeUnit.SECONDS)

现在 get 调用在第一次运行时就成功了。

我无法确定 contextDestroyed 调用是如何干扰请求的常规处理的。我最好的猜测是 spymemcached 的单线程以某种方式在 servlet 之间共享,因此当创建一个 servlet 来处理我们构建过程的验证步骤发送的请求时,它会在我发送的第一个请求之前被销毁,并且我的请求的 servlet 正在使用的 MemcachedClient 将尝试使用同一个线程并受到关闭异常的影响。

(当我们得知我们的 Web 应用程序与我们的 memcached 服务器有太多打开的连接时,我们的团队已经确定需要调用 shutdown。)

于 2019-06-24T16:32:09.477 回答