Amazon S3服务ConnectionPoolTimeoutException:等待来自池的连接超时

时间:2016-08-08 15:01:47

标签: amazon-web-services amazon-s3 timeoutexception

当我在亚马逊上使用s3时,我不断得到丑陋的ConnectionPoolTimeoutException。

问题在于,由于应用程序的前端,我无法在前端完成之前关闭打开的s3对象,所以我已经实现了这个解决方案:

@Autowired
private AmazonS3 s3client; // credentials are set properly.

private static List<S3Object> openedObjects = new ArrayList<S3Object>();

// initialize bucket :
private String bucketName = "myShinyNewBucket";
private synchronized boolean initBucket(){
    try{
        Boolean exists = null;
        try{
            exists = s3client.doesBucketExist(bucketName);
        }catch(Exception e1){
            System.out.println("\n\n\tToo many opened objects ; closing...\n\n");
            deleteOpenedS3Objects();
            exists = s3client.doesBucketExist(bucketName);
        }
        if(exists!=null){
            if(!exists){
                s3client.createBucket(new CreateBucketRequest(bucketName));
            }
            return true;
        }
    }
    catch(Exception e){
        System.out.println("\n\n\tFailed to initialize bucket.\n");
        e.printStackTrace();
    }
    return false;
}

private synchronized void deleteOpenedS3Objects(){
    System.out.println("\n\tClosing opened objects...");
    try{
        for(int i=0 ; i<openedObjects.size() ; i++){
            openedObjects.get(i).close();
            openedObjects.remove(i);
        }
    }catch(Exception e1){
        System.out.println("\tCould not close all opened s3 objects, only the first "+i);
    }
    System.out.println("\tTrying again :\n\n");
}

// GET :
public final String getFromAWS(final String amazonName){
    S3Object s3object = null;

    if(initBucket()){
        try{
            try{
                s3object = s3client.getObject(new GetObjectRequest(bucketName, amazonName));
            }catch(AmazonClientException e){
                deleteOpenedS3Objects();
                s3object = s3client.getObject(new GetObjectRequest(bucketName, amazonName));
            }
            openedObjects.add(s3object);
            return s3object.getObjectContent().getHttpRequest().getURI().toString();
        }catch(Exception e1){
            if (((AmazonS3Exception)e1).getStatusCode() == HttpStatus.SC_NOT_FOUND){
                System.out.println("\n\nNo such object in bucket.\n");
            }
            else{
                System.out.println("\n\n\tCould not read bject from bucket.\n\n");
                e1.printStackTrace();
            }
        }
    }
    return null;
}

然而,例外情况仍在发生。

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:286) ~[httpclient-4.5.1.jar!/:4.5.1]
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263) ~[httpclient-4.5.1.jar!/:4.5.1]
        at sun.reflect.GeneratedMethodAccessor144.invoke(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
        at com.amazonaws.http.conn.ClientConnectionRequestFactory$Handler.invoke(ClientConnectionRequestFactory.java:70) ~[aws-java-sdk-core-1.11.8.jar!/:na]
        at com.amazonaws.http.conn.$Proxy188.get(Unknown Source) ~[na:na]
...

只有当我在控制台中执行ctrl + c时,它是否会进入关闭打开的s3连接的部分:

... Caused by: java.lang.InterruptedException: Operation interrupted
        at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:142) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:306) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:192) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:185) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:107) ~[httpcore-4.4.4.jar!/:4.4.4]
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:276) ~[httpclient-4.5.1.jar!/:4.5.1]
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263) ~[httpclient-4.5.1.jar!/:4.5.1]
        at sun.reflect.GeneratedMethodAccessor144.invoke(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
        at com.amazonaws.http.conn.ClientConnectionRequestFactory$Handler.invoke(ClientConnectionRequestFactory.java:70) ~[aws-java-sdk-core-1.11.8.jar!/:na]
        at com.amazonaws.http.conn.$Proxy188.get(Unknown Source) ~[na:na]
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190) ~[httpclient-4.5.1.jar!/:4.5.1]
        ... 148 common frames omitted


        Too many opened objects. // <-- This is where it catches it.



        Closing opened objects...
        Could not close all opened s3 objects.
        Trying again :




        Failed to initialize bucket.

再一次,遗憾的是,在我将功能留在s3-client类之前,我无法关闭已打开的s3对象。我唯一的希望就是等到TimeoutException发生,抓住它,然后关闭所有打开的对象并再次尝试。 但是,我似乎无法在正确的地方捕捉它。

请帮助。

谢谢。

2 个答案:

答案 0 :(得分:2)

在处理任何类型的文件读写时,我们必须使用try with resources。即使我们遇到任何异常,这也会自动关闭使用的资源。

在我的情况下: S3 读取以进行批量操作时,我得到404,在通过记录错误编写脚本时忽略了该操作,而忘记了在其中关闭连接终于挡住了。

示例片段:

 public void SaveEqualized(){
    imgviewecualizacion.setDrawingCacheEnabled(true);
    Bitmap bitmap = imgviewecualizacion.getDrawingCache();
    File root = Environment.getExternalStorageDirectory();
    File file = new File(root.getAbsolutePath()+"/Android/data/com.example.example/files/Pictures/equalized.jpg");

    try
    {
        file.createNewFile();
        FileOutputStream ostream = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
        ostream.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

注意:

  1. 尝试使用具有 JDK 8 及更高版本支持的资源。
  2. static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } 中声明的所有资源必须实现try()接口。

答案 1 :(得分:0)

我认为sollution是在@ControllerAdvice类中捕获并处理丑陋的TimeoutException。我已经这样做了,到目前为止我没有在应用程序中发生这种情况。我确定后会发布确认信息。