2015-08-21 6 views
6

Ich verwende AWS-S3-Consumer, um in regelmäßigen Abständen Dateien an einer bestimmten Position auf S3 abzurufen. Nach dem Abruf für bestimmte Anzahl der Zeiten, beginnt andernfalls es Ausnahmen wie angegeben,Apache Camel: AWS-S3-Consumer startet mit Timeout für Verbindungspool

Will try again at next poll. Caused by:[com.amazonaws.AmazonClientException - Unable to execute HTTP request: 
Timeout waiting for connection from pool] 
com.amazonaws.AmazonClientException: Unable to execute HTTP request:Timeout waiting for connection from pool 
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:376) ~[aws-java-sdk-1.5.5.jar:na] 
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:202) ~[aws-java-sdk-1.5.5.jar:na] 
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3037) ~[aws-java-sdk-1.5.5.jar:na] 
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3008) ~[aws-java-sdk-1.5.5.jar:na] 
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:531) ~[aws-java-sdk-1.5.5.jar:na] 
at org.apache.camel.component.aws.s3.S3Consumer.poll(S3Consumer.java:69) ~[camel-aws-2.12.0.jar:2.12.0] 
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:187) [camel-core-2.12.0.jar:2.12.0] 
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:114) [camel-core-2.12.0.jar:2.12.0] 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_60] 
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) [na:1.7.0_60] 

Von dem, was ich verstehe, ist der Grund, warum die Verbraucher die verfügbaren Verbindungen aus dem Pool anstrengend sein, wie es jede Umfrage eine neue Verbindung verwendet. Was ich wissen muss, ist, wie man die Ressourcen nach jeder Abfrage freigibt und warum die Komponente selbst das nicht tut.

Camel Version: 2.12

Edit: ich den Verbraucher geänderten benutzerdefinierten S3-Client mit bestimmten Verbindungszeit, maxconnections, maxerrorretry und sockettimeout zu holen, aber nichts. Resultierend ist das selbe.

S3 Client-Konfiguration:

ClientConfiguration clientConfiguration = new ClientConfiguration(); 
    clientConfiguration.setMaxConnections(50); 
    clientConfiguration.setConnectionTimeout(6000); 
    clientConfiguration.setMaxErrorRetry(3); 
    clientConfiguration.setSocketTimeout(30000); 
    main.bind("s3Client", new AmazonS3Client(awsCredentials, clientConfiguration)); 

die Aufgabe AmazonS3Client Namen "s3Client" der Camel Kontext begrenzt ist und mit Camel AWS-S3-Komponente auf Basis Route vorgesehen. Jetzt verwaltet Camel allein diese Ressource.

Erforderliche Lösung: Ich erwarte eine spezifische Lösung für Camel Aws-S3 Consumer und keine generische Java-Lösung, da mir bewusst ist, dass die Verbindung geschlossen werden soll, nachdem ihre Aufgabe erledigt wurde, damit sie freigegeben und erneut verwendet werden kann. Was mich verwirrt, ist, warum Camel das nicht automatisch macht, wenn es mit dem Verbindungspool zur Verfügung gestellt wird oder wenn ich eine Konfiguration speziell vermisse.

Antwort

2

Camel Verbraucherklasse öffnet die Verbindung für jeden "Schlüssel" und erzeugt einen Austausch daraus. Dieser Austausch wird zur Verarbeitung an die Route weitergeleitet, aber nie automatisch geschlossen, auch nicht beim Aufruf von "Stop". Dies hat zur Folge, dass dem Verbindungspool keine freien Verbindungen mehr zur Verfügung stehen. Was getan werden muss, ist, den S3ObjectInputStream aus dem Exchange zu extrahieren und ihn zu schließen.

S3ObjectInputStream s3InputStream = exchange.getIn().getBody(S3ObjectInputStream.class); 
s3InputStream.close(); 

Die Antwort ist ziemlich nah an dem, was die anderen vorschlagen, dass die Verbindung zu schließen ist.Aber wie gesagt, Kamel spezifische Antwort wurde erwartet und eine Erklärung, warum Camel nicht allein behandelt.

+0

Ihre Antwort ist unvollständig. Was ist Ihre Routendefinition und wo schließen Sie den Stream? –

1

Irgendwo, wo Connection Pooling-Konzept das gleiche ist.Wenn Sie nicht in der Lage, eine Verbindung zu erhalten, ist es im Leerlauf, in der Entwicklung müssen wir explizit aufrufen close(), indem Sie prüfen, ob Verbindung Leerlauf. für exmaple:

if(con.isIdle()&& !con.closed()){ 
con.close(); 
} 

Dann erst werden wir die conncetions available.Even bekommen, obwohl die meisten Frameworks sein es besser diesen Code aus unseren Klassen connection abzuschließen.

Edit:

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

Dieser Link wird mürrisch Sie dabei Ihre spezifische Antwort hilft, wie Sie Ihren Code nicht von S3Object Verbindungsklasse angegeben haben.

Edit 2:

Versuchen Sie, diese Methode in Ihrer ClientConfiguration

public ClientConfiguration withConnectionMaxIdleMillis(long connectionMaxIdleMillis) 

könnte dies Ihre Fehler beheben, weil es automatisch die Verbindung geschlossen wird, wenn der Pool Idle-Verbindung ist und nicht wiederverwendet werden.

+0

Ich verstehe diesen Punkt, aber Sie müssen in diesem Fall die Verbindungsinstanz erhalten. Für eine einfache Java-Anfrage hätte ich das sicherlich getan, aber in diesem Fall suche ich nach etwas, das spezifisch für die Camel AWS-S3-Komponente ist. –

+0

Bitte geben Sie Ihren Code von S3Object und seinen Instanzen an? –

+0

@jagdish: Fertig. –