背景 老系统和其他系统对接采用ftp交互(内外网隔离,通过光闸内外网摆渡交互文件.ak),每次对ftp的操作都是新创建连接消耗较大,于是将ftp池化降低ftp创建的消耗,完成系统优化。
介绍 使用依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > <scope > runtime</scope > <optional > true</optional > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.8</version > </dependency > <dependency > <groupId > org.apache.commons</groupId > <artifactId > commons-pool2</artifactId > <version > 2.7.0</version > </dependency > <dependency > <groupId > commons-net</groupId > <artifactId > commons-net</artifactId > <version > 3.7.2</version > </dependency > <dependency > <groupId > org.apache.commons</groupId > <artifactId > commons-lang3</artifactId > <version > 3.9</version > </dependency > <dependency > <groupId > commons-io</groupId > <artifactId > commons-io</artifactId > <version > 2.8.0</version > </dependency >
代码分析 FtpClientFactory FtpClientFactory 继承 org.apache.commons.pool2 包下的BasePooledObjectFactory抽象类。
重写其抽象方法:
1 2 3 4 5 6 7 8 9 10 11 public abstract T create () throws Exception ; public abstract PooledObject<T> wrap (T var1) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @Override public FTPClient create () throws Exception { FTPClient client = new FTPClient(); boolean hasError = false ; try { client.setDefaultPort(config.getPort()); client.setConnectTimeout(config.getConnectTimeout()); client.setDataTimeout(config.getDataTimeout()); client.setDefaultTimeout(config.getSocketTimeout()); client.connect(config.getHost(), config.getPort()); long startTime = System.currentTimeMillis(); if (!client.login(config.getUsername(), config.getPassword())) { hasError = true ; String replyStr = client.getReplyString(); client.logout(); throw new FtpClientCreateException("登录FTP失败!" + replyStr); } if (!FTPReply.isPositiveCompletion(client.getReplyCode())) { hasError = true ; String replyStr = client.getReplyString(); client.disconnect(); throw new FtpClientCreateException("FTP拒绝连接!" + replyStr); } client.setFileType(FTP.BINARY_FILE_TYPE); client.enterLocalPassiveMode(); client.setBufferSize(config.getBufferSize()); logger.info("ftp【{}】链接创建成功,用时:{}毫秒" , config.getHost(), (System.currentTimeMillis() - startTime)); return client; } finally { if (hasError) { closeCon(client); } } } @Override public PooledObject<FTPClient> wrap (FTPClient ftpClient) { return new DefaultPooledObject<>(ftpClient); }
其他方法如下,可根据业务需要修改。
1 2 3 4 5 public void destroyObject (PooledObject<FTPClient> p) public boolean validateObject (PooledObject<FTPClient> p)
FtpClientPool 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class FtpClientPool extends GenericObjectPool <FTPClient > { public FtpClientPool (PooledObjectFactory<FTPClient> factory) { super (factory); } public FtpClientPool (PooledObjectFactory<FTPClient> factory, GenericObjectPoolConfig config) { super (factory, config); } @Override public void returnObject (FTPClient obj) { if (obj != null ) { super .returnObject(obj); } } }
FtpConfig 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 @Data @Configuration @ConfigurationProperties (prefix = "ftp" )public class FtpConfig { private String host; private int port; private String username; private String password; @PostConstruct public void ftpClientPool () { GenericObjectPoolConfig config = new GenericObjectPoolConfig(); config.setTestOnBorrow(true ); config.setTestWhileIdle(true ); config.setMaxTotal(this .poolMaxActive); config.setMaxIdle(this .poolMaxIdle); config.setMinIdle(this .poolMinIdle); config.setMaxWaitMillis(this .poolMaxWait); config.setTimeBetweenEvictionRunsMillis(this .checkIdleTime); FtpClientPool ftpClientPool = new FtpClientPool( new FtpClientFactory(this ), config); FtpUtil.initPool(ftpClientPool); } }
This is copyright.