OSS - 有关于OSSClient的单例化
之前在每个控制层OSSClient都是通过新new的方式创建OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret)进行创建
后期我想应该可以把这个进行单例化
改了一番,单例化是实现了,可以每次调用一个方法时,只有首次会获取成功,第二次虽然连接会是true,但是会显示ossClient实例为null,从而无法继续调用
第一次执行获取bucket的name集合
{ "success": true, "bucketsNames": [ "beijing-oss-1", "huhehaote-oss-1", "qingdao-oss-1", "sugar-oss1", "test-oss-create", "test-oss-create1", "ukyomooc123osstestdemo" ] }
第二次执行
{ "success": true, "bucketsNames": null }
错误信息
2019-12-23 10:03:46.053 WARN 1476 --- [nio-8011-exec-3] com.aliyun.oss : [Unknown]Unable to execute HTTP request: Connection pool shut down
com.aliyun.oss.ClientException: 网络连接错误,详细信息:Connection pool shut down
[ErrorCode]: Unknown
[RequestId]: Unknown
Caused by: java.lang.IllegalStateException: Connection pool shut down
这是因为在每个服务调用后都按照官方demo进行了shutdown
} finally { if(null != ossClient){ ossClient.shutdown(); } }
而我又查了下aliyun开发问题也有相同的问题https://developer.aliyun.com/ask
只不过都是挺久之前的了.
如果完成操作之后使用shutdown方法, 会抛出线程异常, 如果对OSSClient不做任何处理, 每隔60秒就有关闭空闲连接的日志输出(new了2个OSSClient实例, 完成操作之后断点停住):
从第二张图,排行前35中,基本都是基础类型和java、apache、sun的包,只有一个是aliyun的类,而且这个配置类,看第二列,实例数(instances),理论上不可能会达到1W8的客户端同时在连接,再看那些HttpClientBuilder、SocksSocketImpl这些都是与网络请求有关的,OSS的上传也是需要这些,而且数量上,都是在1W8左右
后面去看过代码,每次上传文件到OSS,服务端都是采用先获取授权令牌,然后new OSSClient()去开启一个上传客户端连接,但是后面没有关闭,初步断定是这个地方的问题,随即增加了 ossClient.shutdown();
问题已经解决了,内存也不需要那么大,最后要提醒下大家,用完一定要关闭,很重要!!! ossClient.shutdown();
https://developer.aliyun.com/ask/243394?spm=a2c6h.13524658 OSSClient 每次使用都new 还是 使用单例好,必须shutdown 吗?
您的工程中可以有一个或多个OSSClient。OSSClient可以并发使用。
所以最终以取消掉shutdown()操作为最后操作
单例化ossclient工厂
package com.springboot.oss.entity; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; /** * OSSClient单例化工厂 * 使用ossClient单例化后,不可以再进行shutdown操作 */ @PropertySource(value = "classpath:aliyunConfig.properties") @Component public class OssClientFactory { //volatile是Java提供的一种轻量级的同步机制,在并发编程中,也扮演着比较重要的角色. //同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级,相比使用 //synchronized所带来的庞大开销,倘若能恰当的合理的使用volatile,则wonderful private volatile static OSS client; private OssClientFactory(){} private volatile static OSSClientBuilder ossClientBuilder; private static String endpoint; private static String accessKeyId; private static String accessKeySecret; @Value("${aliyun.endpoint}") public void setEndpoint(String endpoint) { this.endpoint = endpoint; } @Value("${aliyun.accessKey.Id}") public void setAccessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; } @Value("${aliyun.accessKey.Secret}") public void setAccessKeySecret(String accessKeySecret) { this.accessKeySecret = accessKeySecret; } @Bean @Scope("prototype") public static OSS getOSSClient(){ if(client == null){ synchronized(OssClientFactory.class){ if(client==null){ client = getOSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret); } } } return client; // client = getOSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // return client; } public static OSSClientBuilder getOSSClientBuilder(){ System.out.println("获取OSSClientBuilder"); if(ossClientBuilder == null){ System.out.println("OSSClientBuilder为空,创建中"); synchronized(OssClientFactory.class){ if(ossClientBuilder==null){ System.out.println("进入同步实例化OSSClientBuilder"); ossClientBuilder = new OSSClientBuilder(); } } } return ossClientBuilder; } }
获取OSSClientBuilder
OSSClientBuilder为空,创建中
进入同步实例化OSSClientBuilder
list buckets : [OSSBucket [name=beijing-oss-1, creationDate=Fri Dec 20 11:19:37 CST 2019, owner=Owner [name=1932998108284896,id=1932998108284896], location=oss-cn-beijing, ...
获取OSSClientBuilder
list buckets : [OSSBucket [name=beijing-oss-1, creationDate=Fri Dec 20 11:19:37 CST 2019, owner=Owner [name=1932998108284896,id=1932998108284896], location=oss-cn-beijing, ...
您的工程中可以有一个或多个OSSClient。OSSClient可以并发使用。
本文来自博客园,作者:ukyo--夜王,转载请注明原文链接:https://www.cnblogs.com/ukzq/p/12082414.html