阿里OSS连接池无连接可用问题

问题

现状是调用ossClient.getObject()时线程阻塞,且无法释放,经过代码排查后, 发现阿里OSS默认从连接管理器检索可用连接的超时时间为-1(不限制),则一直等待,最终需要服务重启。

解决过程

本地模拟,首先设置最大连接数为3,连接管理器检索可用连接的超时时间改为10秒后则会出现以下情况,多个线程调用第4次ossClient.getObject() 10秒后出现以下异常

2023-04-06 19:32:59.953 [Thread-39] WARN [com.aliyun.oss] - [ExecutorService]The wait 10000 timed out: null
2023-04-06 19:32:59.954 [Thread-39] WARN [com.aliyun.oss] - [Client]Unable to execute HTTP request: null
[ErrorCode]: RequestTimeout
[RequestId]: Unknown
Exception in thread "Thread-39" com.aliyun.oss.ClientException: null
[ErrorCode]: RequestTimeout
[RequestId]: Unknown
	at com.aliyun.oss.common.comm.TimeoutServiceClient.sendRequestCore(TimeoutServiceClient.java:94)
	at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:149)
	at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:85)
	at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:134)
	at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:192)
	at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:153)
	at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:369)
	at com.aliyun.oss.OSSClient.getObject(OSSClient.java:689)
	at com.aliyun.oss.OSSClient.getObject(OSSClient.java:679)
	..
Caused by: java.util.concurrent.TimeoutException
	at java.util.concurrent.FutureTask.get(FutureTask.java:205)
	at com.aliyun.oss.common.comm.TimeoutServiceClient.sendRequestCore(TimeoutServiceClient.java:72)
	... 10 more

通过这次过程分析到,应该是没有连接可用了,为啥没有连接呢,难道用完没有回收吗,通过debug后发现以下内容

none

关键信息如下

leased = 2
available = 0

表示当前可获取的线程池数量为0,被持有的有2两个没有释放

原因

通过以上排查流程,最后明显定位到OSS用完后,没有操作OSSObject.close();,或者返回的数据没有InputStream.close();导致。 最后通过在数据使用完毕后,手动InputStream.close();,问题得以解决。

我们遇到的问题是因为有部分业务异常导致没有正常的close,如果出现过多次没有close的情况,导致最终没有连接卡死情况,最后需要重启服务器。

更新日期:
作者: dingqw