Java库AmazonS3Client.getObject永远不会返回

时间:2014-11-21 00:25:31

标签: java amazon-s3

我遇到的问题似乎是AmazonS3Client.getObject的调用永远不会返回;这种情况每天都在发生在我们身上,我相信当S3运行它的每日到期工作时。

似乎没有一种方法可以为此请求指定超时值,并且它会导致我们的线程池无限期地被阻塞,使得当它们足够无限期挂起时,我们的整个实例都没有响应。

有没有办法克服?我已经走了Thread.interrupt路径,但我不确定该信号是否会被遵守。

以下是它被卡住的堆栈跟踪:

"image-s3-dispatcher-10187" - Thread t@10481
   java.lang.Thread.State: TIMED_WAITING
  at sun.misc.Unsafe.park(Native Method)
  - parking to wait for <7945c7e6> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  at java.util.concurrent.locks.LockSupport.parkUntil(LockSupport.java:267)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitUntil(AbstractQueuedSynchronizer.java:2130)
  at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:129)
  at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:281)
  at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:62)
  at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:176)
  at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:172)
  at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:100)
  at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:212)
  at org.apache.http.impl.conn.PoolingClientConnectionManager$1.getConnection(PoolingClientConnectionManager.java:199)
  at sun.reflect.GeneratedMethodAccessor22.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at com.amazonaws.http.conn.ClientConnectionRequestFactory$Handler.invoke(ClientConnectionRequestFactory.java:70)
  at com.amazonaws.http.conn.$Proxy9.getConnection(Unknown Source)
  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
  at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:384)
  at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:232)
  at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3528)
  at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:1111)
  at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:984)
  at com.spingo.s3client.S3Client$$anonfun$read$1.apply(S3Client.scala:110)

所有8个挂起的请求都是针对文件&lt; = 10kb,有些请求的时间长达15分钟。

1 个答案:

答案 0 :(得分:2)

执行以下操作后:

  • 升级至最新aws-java-sdk(1.9.7)(自1.9.6)
  • 明确关闭S3Object#getObjectContent
  • 返回的流
  • 禁用亚马逊的到期规则。

......这个问题,一周内第一次停止了。难以分辨哪些事情(如果有的话)导致改善。

如果是因为没有明确关闭流,那么,那年我一直在使用aws-java-sdk几个月没有任何问题。并且,在每天的确切时间,所有实例的问题都表现得很奇怪。

如果它禁用亚马逊上的到期规则,那么,我会报告当我重新启用时会发生什么。

如果它正在升级最新的aws-java-sdk,则没有提及在发行说明中解决的观察到的无限块问题。

虽然我很想知道究竟是什么问题,但我并不急于让自己试着再次破坏它。它只能在每天的特定时间再现。 :/

-

<强>更新

问题实际上并未解决;它恰好有一天没有发生。今天早上又在不同的时间再次发生。

在AWS论坛上运气更好。似乎它都回溯到apache http库的问题。留下面包屑让我的网民们受益:

https://forums.aws.amazon.com/thread.jspa?messageID=585774&#585774

-

更新2

更新apache http库没有帮助。也没有回滚AWS客户端。

我们正在检查一个物体是否存在的区域。为此,我们调用AmazonS3Client#getObject并检查异常,认为S3Object#getObjectContent是实际获取流的内容。阅读文档让我相信这一点。但是,在阅读源代码时,我开始意识到getObjectContent是一个简单的getter,而库渴望分配流。由于我们没有意识到这一点,如果我们没有拨打S3Object#getObjectContent,我们就不打算在流上调用close。

所以,故事的道德:任何时候你打电话AmazonS3Client#getObject,关闭流。