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可以并发使用。
OSS - 有关于OSSClient的单例化的更多相关文章
- Kotlin入门(28)Application单例化
Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...
- QT中实现应用程序的单例化
一介绍 通过编写一个QSingleApplication类,来实现Qt程序的单例化,原文的作者是在Windows Vista + Qt4.4 下实现的,不过应用在其他平台上是没问题的.(本文是我在ht ...
- 三、singleton(单例化)一个对象的几种方法
方案一:私有化构造器,通过static final域 @Test public void test13() { A215 a=A215.a; A215 b=A215.a; System.out.pri ...
- 慎把“DataContext”静态化 或则单例
之前在项目里由于把DataContext静态化,最后在测试阶段发现了很多奇怪的问题,后来经过同事的指点 然后上网搜了一翻终于发现 MSDN上说: "请不要试图重用 DataContext ...
- 设计模式——单例设计模式(C++实现)
#ifndef SINGLETONHOLDER_INC #define SINGLETONHOLDER_INC template<class T> class SingletonHolde ...
- qt 共享内存 单例
QT 进程间通信之古老的方法(内存共享) 让QT只运行一个实例 以上两篇文章中分别讲述了QSharedMemory的不同作用,第一篇讲了进程间通信,第二篇讲述了怎么让应用程序只 ...
- 转--python 中写单例
原文地址 原文地址2 Python中的单例模式的几种实现方式的及优化 阅读目录(Content) 单例模式 实现单例模式的几种方式 1.使用模块 2.使用装饰器 3.使用类 4.基于__new__方法 ...
- java 单例
Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例. 饿汉式和懒汉式区别 从名字上来说,饿汉和懒汉, 饿汉就是类一旦加载,就把单例初始化完成,保证 ...
- iOS开发——高级篇——iOS中常见的设计模式(MVC/单例/委托/观察者)
关于设计模式这个问题,在网上也找过一些资料,下面是我自己总结的,分享给大家 如果你刚接触设计模式,我们有好消息告诉你!首先,多亏了Cocoa的构建方式,你已经使用了许多的设计模式以及被鼓励的最佳实践. ...
随机推荐
- K8S从入门到放弃系列-(8)kube-apiserver 高可用配置
摘要: 前面几篇文章,就是整个的master节点各组件的部署,上面我们提到过,k8s组件中,kube-controller-manager.kube-scheduler及etcd这三个服务高可用,都是 ...
- 【C++札记】new和delete
介绍 1.malloc,free和new,delete区别. a.malloc,free是C/C++的标准库函数.new,delete是c++的操作符. b.malloc申请的是内存,严格意义不是&q ...
- python — 索引与pymysql模块
1. 索引 1.1 索引原理 1.什么是索引 ?-- 目录 索引就是建立起的一个在存储表阶段就有的一个存储结构,能在查询的时候加速. 2.索引的重要性: 读写比例 为 10:1,所有读(查询)的速度就 ...
- Java中编码问题
在开发过程中经常会遇到一会乱码问题,不是什么大问题,但是也挺烦人的,今天来将我们开发总结的经验记录下来,希望可以给大家一些帮助. 一些概念: 字符:人们使用的记号,抽象意义上的一个符号.比如:‘1’, ...
- base全家桶的安装使用方法
base编码是Binary-to-text encoding的一种实现方法,它可以把二进制数据(含不可打印的字符)编码成可打印字符序列. 本文会不定时收录“base全家桶”:base64.base32 ...
- js 根据 数组条件 简单查询的方法临时保存
let array = [{ date: '2016-05-02', name: 'Ethan', status: 'success', total: '81' }, { date: '2016-05 ...
- Once in a casino CodeForces - 1120B (暴力)
大意: 给定两个字符串$a,b$, 每个字符为$0-9$, 每次操作将$a$中相邻两位加$1$或减$1$, 操作后每个数仍要为$0-9$, 求最少操作使$a$变成$b$. 先不考虑范围, 判断是否成立 ...
- 开发人员需求能kill杀死其它阻塞自己的会话,测试发现需要alter system权限有风险
模拟开发人员需求,可以杀死其它阻塞自己的会话1.能有查询阻塞会话确认的权限SQL> grant select on v_$session to testa;SQL> grant selec ...
- Linux中 ls -l 命令显示结果中的每一列的含义
图片转载自:https://blog.csdn.net/zhuoya_/article/details/77418413 简单解释下: 1.第一列颜色框:文件类型列,这里简单描述几种常见类型,d表示目 ...
- C语言数组不知道输入几个整数以及输入一直到为0
输入一直到为0: ){ } 数组不知道输入几个整数: ],num=; for(;;num++){ scanf("%d",&array[num]); if(getchar() ...