前言
最最一开始, 我们有多台服务器分布式部署了具有接收用户上传图片功能的系统, 为了将上传的图片存储到一起(为了方便用户预览图片, 查询图片, 由于没有部署类似于HDFS, fastDFS这种分布式文件系统, 只是基于Linux存储简单的图片, 需要将图片集中到一起来进行管理), 我们就需要在用户上传图片之后, 将多台服务器上的零散的图片, 传输并存储在一台集中的图片服务器上.
其拓扑图如下:
为此, 需要基于Java来实现服务期间文件的传输.
SCP命令
在Linux系统中, 进行2个主机间复制文件的命令是scp, 它是基于ssh登录, 有Security的文件复制操作.
1 2 3 4 5 6
| 命令基本格式: scp [可选参数] file_source file_target 例: scp /home/admin/a.txt root@172.19.21.75:/home/root 将本地`/home/admin/a.txt`拷贝到远程`172.19.21.75`主机的`/home/root`目录下, 登录名为`root`,之后输入root用户的密码就可以了.
|
此处, 我们使用ch.ethz.ganymed包的相关工具类, 来实现ssh登录并进行scp操作来满足我们的需求.
实现步骤
Maven引入依赖包
1 2 3 4 5
| <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>build210</version> </dependency>
|
实现
1.实现服务器间SSH登录的工具类
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 49 50 51 52 53 54 55 56 57 58 59 60
| import ch.ethz.ssh2.Connection; import java.io.File; import java.io.IOException; * SSH工具类 */ public class SSHUtil { * 根据用户名/密码进行SSH连接 */ public static Connection login(String hostname, int port, String username, String password) throws IOException { Connection conn = new Connection(hostname, port); try { conn.connect(); boolean isAuthenticated = conn.authenticateWithPassword(username, password); if (isAuthenticated == false) { throw new IOException("SSH认证失败"); } } catch (IOException e) { e.printStackTrace(); throw e; } return conn; } * 根据公钥进行SSH连接 */ public static Connection loginByPublicKey(String hostname, int port, String username, File keyFile, String password) throws IOException { Connection conn = new Connection(hostname, port); try { conn.connect(); boolean isAuthenticated = conn.authenticateWithPublicKey(username, keyFile, password); if (!isAuthenticated) { throw new IOException("SSH认证失败"); } } catch (IOException e) { e.printStackTrace(); throw e; } return conn; } }
|
2.进行文件的传输
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| * 传输文件 * * @param file 文件 */ public void fileTransfer(MultipartFile file) { if (file == null) { return; } try { Connection con = SSHUtil.loginByPublicKey(serverIP, serverPort, "root", new File(publicKey), null); SCPClient scpClient = con.createSCPClient(); scpClient.put(uploadPath + "/" + file.getOriginalFilename(), targetPath); } catch (Exception e) { logger.error("文件传输发生异常", e); } }
|
同理, 可根据scpClient.get(String remoteFile, String localTargetDirectory);
来复制远程文件到本地目录下.