13

Ho lavorato per un po 'di tempo con aws java API con non tanti problemi. Attualmente sto usando la versione 1.5.2 della libreria."ConnectionPoolTimeoutException" durante l'iterazione di oggetti in S3

Quando sto iterazione gli oggetti all'interno di una cartella con il seguente codice:

AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(MyClass.class.getResourceAsStream("AwsCredentials.properties"))); 

String s3Key = "folder1/folder2"; 


String bucketName = Constantes.S3_BUCKET; 
String key = s3Key +"/input_chopped/"; 

ObjectListing current = s3.listObjects(new ListObjectsRequest() 
     .withBucketName(bucketName) 
     .withPrefix(key)); 

boolean siguiente = true; 

while (siguiente) {  

    siguiente &= current.isTruncated(); 
    contador += current.getObjectSummaries().size(); 

    for (S3ObjectSummary objectSummary : current.getObjectSummaries()) {   
     S3Object object = s3.getObject(new GetObjectRequest(bucketName, objectSummary.getKey())); 
     System.out.println(object.getKey()); 
    } 

    current=s3.listNextBatchOfObjects(current); 

} 

Gist: Link: https://gist.github.com/fgblanch/6038699 sto ottenendo la seguente eccezione:

INFO (AmazonHttpClient.java:358) - Unable to execute HTTP request: Timeout waiting for connection from pool 
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool 
    at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:232) 
    at org.apache.http.impl.conn.PoolingClientConnectionManager$1.getConnection(PoolingClientConnectionManager.java:199) 
    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 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784) 
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:315) 
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:199) 
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:2994) 
    at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:918) 
    at com.madiva.segmentacion.tests.ListaS3.main(ListaS3.java:177) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caught an AmazonClientException, which means the client encountered a serious internal problem while trying to communicate with S3, such as not being able to access the network. 
Error Message: Unable to execute HTTP request: Timeout waiting for connection from pool 

Qualsiasi idea di come per evitare questo errore. Succede solo in cartelle con un numero di oggetti, in questo caso all'interno c'erano 463 file. Grazie

risposta

23

Ho scoperto che S3Object apre una connessione per ogni oggetto. Ciò non viene liberato anche se l'oggetto è garbage collection, quindi è necessario eseguire object.close(), per liberare la connessione al pool.

Così il codice corretto sarebbe:

for (S3ObjectSummary objectSummary : current.getObjectSummaries()) {   
     S3Object object = s3.getObject(new GetObjectRequest(bucketName, objectSummary.getKey()));    
     System.out.println(object.getKey()); 
     object.close(); 
    } 
+1

https://forums.aws.amazon.com/message.jspa?messageID=471149 –

+1

@KevinMeredith era la mia domanda nei forum aws; P – Fgblanch

+2

Questo è stato di grande aiuto :) – ZZzzZZzz

1

Verificare se HttpResponseHandler sta chiudendo le connessioni dal pool. AmazonHttpClient ha il parametro 'leaveHttpConnectionOpen' che indica che la connessione deve essere chiusa o meno.

+0

Grazie per l'intuizione, ho scaricato AWS fonti biblioteca e ho trovato che ogni S3Object si tratta di una connessione aperta. Quindi è necessario eseguire object.close() per liberare quella connessione – Fgblanch