Java实现服务器间文件传输

文章目录
  1. 前言
  2. SCP命令
  3. 实现步骤
    1. Maven引入依赖包
    2. 实现
      1. 1.实现服务器间SSH登录的工具类
      2. 2.进行文件的传输

前言

最最一开始, 我们有多台服务器分布式部署了具有接收用户上传图片功能的系统, 为了将上传的图片存储到一起(为了方便用户预览图片, 查询图片, 由于没有部署类似于HDFS, fastDFS这种分布式文件系统, 只是基于Linux存储简单的图片, 需要将图片集中到一起来进行管理), 我们就需要在用户上传图片之后, 将多台服务器上的零散的图片, 传输并存储在一台集中的图片服务器上.

其拓扑图如下:
[img]

为此, 需要基于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();
// 通过publicKey file登录
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 {
// 建立认证登录
// a方式, 通过用户名/密码连接
// Connection con = SSHUtil.login(serverIP, serverPort, "root", "123456");
// b方式, 通过公钥连接
// publicKey为ssh公钥, 此处值为/root/.ssh/id_rsa
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);来复制远程文件到本地目录下.