阿里云OSS线程增长问题分析
生活随笔
收集整理的這篇文章主要介紹了
阿里云OSS线程增长问题分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
線上出現運行幾個小時后,阿里云OSS無法進行操作問題,分析發現線程數線性增長,很快到達最大線程數,最后分析代碼/查找OSS文檔發現是使用OSSObject時沒有close導致的,因為OSSObject封裝了inputStream,未關閉會導致http連接一直處于open狀態,無法進行回收,最后到達最大連接,徹底無法訪問OSS。
隨后對OSSClient代碼進行分析,看下為何會線程線性增長;
1,查看OSSClient定義
public OSSClient(String endpoint, CredentialsProvider credsProvider, ClientConfiguration config) {this.credsProvider = credsProvider;config = config == null ? new ClientConfiguration() : config;if (config.isRequestTimeoutEnabled()) {this.serviceClient = new TimeoutServiceClient(config);} else {//新建DefaultServiceClient對象this.serviceClient = new DefaultServiceClient(config);}initOperations();setEndpoint(endpoint);}2,查看DefaultServiceClient,定義了httpclient包里的PoolingHttpClientConnectionManager(http連接池管理器),并單獨起線程進行連接回收策略
public DefaultServiceClient(ClientConfiguration config) {super(config);//使用了httpClient包里的連接管理器,重點看這里this.connectionManager = createHttpClientConnectionManager();this.httpClient = createHttpClient(this.connectionManager);RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();//連接超時時間requestConfigBuilder.setConnectTimeout(config.getConnectionTimeout());requestConfigBuilder.setSocketTimeout(config.getSocketTimeout());requestConfigBuilder.setConnectionRequestTimeout(config.getConnectionRequestTimeout());//。。。。。省略代碼this.requestConfig = requestConfigBuilder.build();} protected HttpClientConnectionManager createHttpClientConnectionManager() {//。。。。省略代碼Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register(Protocol.HTTP.toString(), PlainConnectionSocketFactory.getSocketFactory()).register(Protocol.HTTPS.toString(), sslSocketFactory).build();//使用httpclient的http連接池管理器PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);//設置最大連接,默認1024connectionManager.setDefaultMaxPerRoute(config.getMaxConnections());connectionManager.setMaxTotal(config.getMaxConnections());connectionManager.setValidateAfterInactivity(config.getValidateAfterInactivity());connectionManager.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(config.getSocketTimeout()).setTcpNoDelay(true).build());if (config.isUseReaper()) {//起新線程執行連接回收策略,重點關注IdleConnectionReaper.setIdleConnectionTime(config.getIdleConnectionTime());IdleConnectionReaper.registerConnectionManager(connectionManager);}return connectionManager;}3,連接回收策略,定時去遍歷連接管理器,然后調用httpclient的連接回收策略。
public void run() {while (true) {if (shuttingDown) {getLog().debug("Shutting down reaper thread.");return;}//每次休眠五秒try {Thread.sleep(REAP_INTERVAL_MILLISECONDS);} catch (InterruptedException e) {}try {List<HttpClientConnectionManager> connectionManagers = null;synchronized (IdleConnectionReaper.class) {connectionManagers = (List<HttpClientConnectionManager>)IdleConnectionReaper.connectionManagers.clone();}//遍歷所有連接管理器for (HttpClientConnectionManager connectionManager : connectionManagers) {try {//調用httpclient的回收連接方法,回收過期連接與超時空閑連接connectionManager.closeExpiredConnections();connectionManager.closeIdleConnections(idleConnectionTime, TimeUnit.MILLISECONDS);} catch (Exception ex) {getLog().warn("Unable to close idle connections", ex);}}} catch (Throwable t) {getLog().debug("Reaper thread: ", t);}}}4,總結,OSSClient實際是基于httpclient進行接口調用,并使用PoolingHttpClientConnectionManager進行連接管理,單獨起線程進行連接的定時回收。
總結
以上是生活随笔為你收集整理的阿里云OSS线程增长问题分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视频数据丢失怎么办 怎样找回丢失的视频数
- 下一篇: Akka Actors入门案例解析