当我在亚马逊上使用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发生,抓住它,然后关闭所有打开的对象并再次尝试。 但是,我似乎无法在正确的地方捕捉它。
请帮助。
谢谢。
答案 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();
}
}
注意:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
中声明的所有资源必须实现try()
接口。答案 1 :(得分:0)
我认为sollution是在@ControllerAdvice类中捕获并处理丑陋的TimeoutException。我已经这样做了,到目前为止我没有在应用程序中发生这种情况。我确定后会发布确认信息。