起因:
因项目使用spring boot 服务以jar方式运行,每次更新都需要对不同模块、不同目录进行文件上传、服务重启等操作,同时文件上传必须使用SFTP,这就导致了需要开多个客户端工具,需要在不同文件目录中来回切换。
这种操作方式效率低、浪费时间,于是想着找开源运维工具,能远端一键部署,奈何网上找了一圈,不是学习成本高就是有使用限制。最后在知乎的一篇文章中看到了一个无需远端服务的Java运维工具,仅需配置好XML即可实现上传文件、执行命令的操作,于是试用一波,无奈要License才能用。想想算了,既然你能用Java搞出来,那我自己整一个出来,高度符合自己使用需求,岂不更妙!
Go! Go! Go! 动起来!
过程:
Google一把,使用Java进行SSH连接,找到不少的博客资料,大多都是使用 JSch 来实现远端链接进行操纵的,那就来了解下它吧,如果满足最基础的几点要求(1、远端链接;2、SFTP上传文件;3、远端执行命令)就可以开始动手Code了。
JSch 官网:http://www.jcraft.com/jsch/, 嗯,老旧的版面风格,还大绿色的,比OSC的的绿色还亮眼啊!不过好东西还挺多的,各种纯JAVA实现的工具,不过暂时我不关心它们,我就了解下JSch。嗯,很好,支持SSH2链接远端,支持文件上传操作,支持远端执行命令。OK,可以动手Code了,容我找找它的MAVEN地址。Oh, shit! 最后更新时间16年9月,看样子不是发展到头了,就是没人维护了。再搜罗一下,应该还有同类开源包,若不其然,Apache有在维护一个项目:SSHD,这次先看看它的MAVNE更新情况再说。嗯,不错,18年还有更新,那继续吧!
SSHD 官网:http://mina.apache.org/sshd-project/,同样了解下它是否满足我的基础要求。ok,同样满足,那不多说咯,了解Api,开始上手了。
0、MAVEN配置
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>1.7.0</version>
</dependency>
1、远端链接
SshClient client = SshClient.setUpDefaultClient();
client.start();
ConnectFuture connectFuture = client.connect("user", "ip", port); // 建立连接
connectFuture.await();
ClientSession session = connectFuture.getSession();
session.addPasswordIdentity(remoteLink.getPassword());
AuthFuture authFuture = session.auth(); // 验证身份
authFuture.await();
if(!authFuture.isSuccess()) {
System.out.println("远端连接失败!");
}
SftpClient sftpClient = session.createSftpClient(); // 建立sftp连接
2、SFTP上传文件
OutputStream outputStream = sftpClient.write("remoteFile");
Files.copy(Paths.get("localFile"), outputStream);
outputStream.close();
3、远端执行命令
session.executeRemoteCommand("cmd", System.out, StandardCharsets.UTF_8);
SSHD的使用异常简单,就上面的几行代码就达到了我的目的。
使用SSHD构建一个完整的项目,实现远端一键部署的需求,代码参见:https://github.com/clyy/remote-deploy。
-----------------------------------------------------------------------------------------------------------------------------------------------
注意:远端执行命令,是non-interactive + non-login模式,在执行命令时不会加载环境变量配置,这就会引起一些意外,比如乱码。对于这种情况,建议手动强制进行环境变量加载,相关内容可以参考: