最近、FTPアップロードツールを作成し、ApacheのFTPClientを使用しています。アップロード効率を改善するために、私はマルチスレッドアプローチを採用しましたが、各スレッドによるftpClientオブジェクトの頻繁な作成と破壊は必然的に不必要なオーバーヘッドを引き起こします。したがって、ここでFTPClient接続プールを使用することをお勧めします。 Apache APIを慎重に調べて、FTPClientPoolの実装がないことがわかったので、自分でFTPClientPoolを書かなければなりませんでした。以下は、参照用の接続プールを開発するプロセス全体を紹介します。
オブジェクトプールについて
一部のオブジェクトは、データベース接続など、オーバーヘッドが比較的高くなっています。オブジェクトの頻繁な作成と破壊によって引き起こされるパフォーマンス消費を減らすために、オブジェクトプーリングの技術を使用してオブジェクトの再利用を実現できます。オブジェクトプールは、オブジェクトプール内のオブジェクトのライフサイクルを管理し、オブジェクトを取得およびリリースする方法を提供し、クライアントがオブジェクトプールでオブジェクトを簡単に使用できるようにするメカニズムを提供します。
自分でオブジェクトプールを実装したい場合は、通常、次の機能を完了する必要があります。
1.プールに使用可能なオブジェクトがある場合、オブジェクトプールはクライアントに戻ることができるはずです。
2。クライアントがオブジェクトをプールに戻した後、それらはそれらを再利用できます。
3.オブジェクトプールは、クライアントの増大するニーズを満たすために新しいオブジェクトを作成できます
4.オブジェクトのライフサイクルを終了するためにプールを適切に閉鎖するメカニズムがあります
Apacheのオブジェクトプールツールキット
独自のオブジェクトプールの開発を促進するために、Apacheが提供する共通プールツールキットには、共通オブジェクトプールを開発するためのいくつかのインターフェイスと実装クラスが含まれています。 2つの最も基本的なインターフェイスは、ObjectPoolとPoolableObjectFactoryです。
ObjectPoolインターフェイスにはいくつかの基本的な方法があります。
1。AddObject():プールにオブジェクトを追加します
2。brobroAbject():クライアントはプールからオブジェクトを借ります
3。returnObject():クライアントはオブジェクトをプールに返します
4。Close():オブジェクトプールを閉じ、メモリをきれいにし、リソースをリリースします。
5。SetFactory(ObjectFactory Factory):プールにオブジェクトを作成するには、工場が必要です。
PoolableObjectFactoryインターフェイスのいくつかの基本的な方法:
1。MakeObject():オブジェクトを作成します
2。destoryObject():オブジェクトを破壊します
3。BalidateObject():オブジェクトがまだ使用可能かどうかを確認します
上記の2つのインターフェイスを通して、自分でオブジェクトプールを実装できます。
例:FTPCLIENTオブジェクトプールを開発します
最近、HDFのファイルをFTPサーバーのグループにアップロードする必要があるプロジェクトが開発されています。アップロード効率を向上させるために、アップロードにマルチスレッドメソッドを使用することを自然に検討します。 FTPをアップロードしたツールは、Apache Common-NetパッケージのFTPClientですが、ApacheはFTPClientPoolを提供しません。したがって、FTPClientが作成および破壊される回数を減らすために、FTPClient Poolを開発してFTPClient接続を再利用しました。
上記の紹介を通じて、Apacheが提供する共通プールパッケージを使用して、接続プールの開発を支援できます。シンプルなオブジェクトプールを開発するには、Common-PoolパッケージにObjectPoolとPoolableObjectFactoryインターフェイスを実装するだけです。私が書いた実装を見てみましょう:
ObjectPoolインターフェイスの実装FTPClientPoolを作成します
java.io.ioexception; Import java.util.nosuchelementexception; Import java.util.concurrent.arrayblockingqueue; Import java.util.concurrent.blockingqueue; Import java.util.concurrent.timeunit; Import org.apache.commons.net.ntp.tp.tp.ptp.ptpcl org.apache.commons.pool.objectpool; import org.apache.commons.pool.poolableobjectfactory;/*** ftpclient接続プール*@author天国*/パブリッククラスftpclientpool emplments objectpool <ftpclient> {private static intic intic defaultize = 10;プライベートファイナルブロッキングキュー<ftpclient>プール。プライベートファイナルFTPClientFactory Factory; / ** *接続プールの初期化、ftpclientインスタンスを提供するために工場を挿入する必要があります * @param Factory * @throws Exception */ public ftpclientpool(ftpclientFactory Factory)スロー例外{this(default_pool_size、factory); } / ** * * @param maxpoolsize * @param Factory * @Throws Exception * / public ftpclientpool(int poolsize、ftpclientFactory Factory)スロー{this.factory = factory;プール= new arrayblockingqueue <ftpclient>(poolsize*2); initpool(poolsize); } /** *接続プールの初期化、ftpclientインスタンスを提供するために工場を挿入する必要があります * @param maxpoolsize * @throws例外 * /private void initpool(int maxpoolsize)スロー{for }} / *(nonjavadoc) * @see org.apache.commons.pool.objectpool#brobreobject() * / public ftpclient borounobject()Throws Exception、nosuchelementexception、IllegalStateException {ftpclient client = pool.take(); if(client == null){client = factory.makeobject(); addObject(); } else if(!factory.validateObject(client)){//渡されないことを確認//オブジェクトをInvalidateObject(client); //プールに新しいオブジェクトを作成して追加します= Factory.MakeObject(); addObject(); }クライアントを返します。 } / *(nonjavadoc) * @see org.apache.commons.pool.objectpool#returnobject(java.lang.object) * / public void returnobject(ftpclientクライアント)スロー例外{((client!= null)&&!pool.! } catch(ioexception e){e.printstacktrace(); }}} public void invalidateObject(ftpclientクライアント)スロー例外{// client invalidate invalidate client pool.remove(client); } / *(nonjavadoc) * @see org.apache.commons.pool.objectpool#addobject() * /public void addobject()Slows Exception、IllegalStateException、UnsupportedoperationException {//オブジェクトをQueue. } public int getNumidle()throws unsupportedoperationexception {return 0; } public int getNumActive()throws unsupportedoperationexception {return 0; } public void clear()throws exception、unsupportedoperationexception {} / *(nonjavadoc) * @see org.apache.commons.pool.objectpool#close() * / public void close()throws exception {while(pool.iterator()。hasnext()){ftpclient client = pool.take(); Factory.DestroyObject(クライアント); }} public void setFactory(PoolableObjectFactory <FTPClient> Factory)IllegalStateException、UnsupportedoperationException {}}別のPoolableObjectFactoryインターフェイスの実装FTPClientFactoryを書きます
java.io.ioexception; import org.apache.commons.net.ftp.ftpclient; Import org.apache.commons.net.ftp.ftpreply; import org.apache.commons.pool.poolableobjectfactory; import org.slf4j.logger; import org.slf4j.loggerfur com.hdfstoftp.util.ftpclientexception;/*** ftpclient Factoryクラスは、ftpclient Factory*@author Heaven*/public class ftpclientFactoryを介してftpclientインスタンスの作成と破壊を提供します。 private ftpclientConfigure config; // ftpclientの関連するパラメーターの構成を容易にするために、工場にパラメーターオブジェクトを一時停止しますpublic ftpclientFactory(ftpclientconfigure config){this.config = config; } / *(nonjavadoc) * @see org.apache.commons.pool.poolableobjectactory#makeobject() * / public ftpclient makeobject()throws exception {ftpclient ftpclient = new ftpclient(); ftpclient.setConnectTimeout(config.getClientTimeout()); try {ftpclient.connect(config.gethost()、config.getport()); int Reply = ftpclient.getReplyCode(); if(!ftpreply.ispositiveCompletion(reply)){ftpclient.disconnect(); logger.warn( "ftpserver拒否接続"); nullを返します。 } boolean result = ftpclient.login(config.getUsername()、config.getPassWord()); if(!result){throw new ftpclientException( "ftpclientログインFailed!username:" + config.getusername() + "; password:" + config.getPassword()); } ftpclient.setFileType(config.getTransferfileType()); ftpclient.setBufferSize(1024); ftpclient.setControlencoding(config.getEncoding()); if(config.getPassiveMode()。 }} catch(ioexception e){e.printstacktrace(); } catch(ftpclientexception e){e.printstacktrace(); } ftpclientを返します。 } / *(nonjavadoc) * @see org.apache.commons.pool.poolableObjectactory#DestroyObject(java.lang.object) * / public void DestroyObject(ftpclient ftpclient)スロー例}} catch(ioexception io){io.printstacktrace(); }最後に{//最終的なコードの接続を切断する必要があることに注意してください。そうしないと、FTP接続が占有されます{ftpclient.disconnect(); } catch(ioexception io){io.printstacktrace(); }}} / *(nonjavadoc) * @see org.apache.commons.pool.poolableobjectfactory#validateObject(java.lang.object) * / public boolean validateObject(ftpClient ftpclient){try {return ftpclient.nendnoop(); } catch(ioException e){new runtimeException( "クライアントの検証に失敗した:" + e、e); }} public void ActivateObject(ftpclient ftpclient)スロー例外{} public void passivateObject(ftpclient ftpclient)スロー例外{}}最後に、パラメーターオブジェクトを工場に渡して、FTPClientのいくつかのパラメーターを設定できるようにすることをお勧めします
Package org.apache.commons.pool.impl.contrib;/** * ftpclient構成クラス、ftpclient * * @author haven */public class ftpclientconfigureの関連する構成をカプセル化します{private string host;プライベートインターポート;プライベート文字列ユーザー名;プライベート文字列パスワード。プライベート文字列passivemode;プライベート文字列エンコーディング; private int clientTimeOut; private int threadnum; Private Int TransferFileType;プライベートブールの名前変更済み; Private int retrytimes; public string gethost(){return host; } public void sethost(string host){this。 host = host; } public int getport(){return port; } public void setport(int port){this。 port = port; } public string getUsername(){return username; } public void setUsername(string username){this。 username = username; } public string getPassWord(){パスワードを返します。 } public void setPassword(String Password){this。パスワード=パスワード; } public string getPassiveMode(){return passivemode; } public void setPassiveMode(string passivemode){this。 passivemode = passivemode; } public string getEncoding(){return encoding; } public void setEncoding(string encoding){this。 encoding = encoding; } public int getClientTimeout(){return ClientTimeout; } public void setClientTimeout(int clientTimeout){this。 clientTimeout = clientTimeout; } public int getthreadnum(){return threadnum; } public void setthreadnum(int threadnum){this。 threadnum = threadnum; } public int getTransferfileType(){return transferFileType; } public void setTransferfileType(int transferFileType){this。 TransferFileType = TransferFileType; } public boolean isrenameuploaded(){return rater renameuploaded; } public void setrenameuploaded(boolean renameuploaded){this。 renameuploaded = renameuploaded; } public int getRetryTimes(){return retrytimes; } public void setretrytimes(int retrytimes){this。 retrytimes = retrytimes; } @Override public String toString(){return "ftpclientconfig [host =" + host + "/n port =" + port + "/n username =" + username + "/n password =" + password + "/n passivemode =" + passivemode + "/n encoding =" + encoding + "/n client -nupt =" + " +" "/n TransferFileType =" + TransferFileType + "/n renameuploaded =" + renameuploaded + "/n retrytimes =" + retrytimes + "]"; }}FTPClientPool Connection Poolクラスは、FTPClientオブジェクトのライフサイクルを管理し、融資、計画、およびプールの破壊を担当します。 FTPClientPoolクラスは、このエンジニアリングクラスによってオブジェクトを作成および破壊するために使用されるFTPClientFactoryクラスに依存します。 FTPClientFactoryは、FTPClientの構成パラメーターのカプセルのカプセルを担当するFTPClientConfigureクラスにも依存しています。この時点で、FTPClient接続プールが開発されました。
FTPClientPoolでFTPCLIENTオブジェクトを管理および保存するためにArrayBlockingQueueが使用されることに注意する必要があります。キューのブロックについては、私の記事を参照してください:[Java Concurrency] BlockingQueue
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。