@@ -9,7 +9,7 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
RUN mkdir -p /root/neutrino-proxy/config
|
||||
WORKDIR /root/neutrino-proxy
|
||||
COPY ./target/neutrino-proxy-client.jar /root/neutrino-proxy/neutrino-proxy-client.jar
|
||||
COPY ./src/main/resources/app-copy.yml /root/neutrino-proxy/config/app.yml
|
||||
COPY src/main/resources/app-copy.yml /root/neutrino-proxy/config/app.yml
|
||||
#VOLUME ["/root/neutrino-proxy"]
|
||||
ENTRYPOINT ["java","-jar","neutrino-proxy-client.jar","config=./config/app.yml"]
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.javpower</groupId>
|
||||
<artifactId>neutrino-proxy-client-spring-boot-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
<packaging>jar</packaging>
|
||||
<version>2.0.1</version>
|
||||
<name>neutrino-proxy-client-spring-boot-starter</name>
|
||||
<description>a tool about easy neutrino-proxy-client</description>
|
||||
<url>https://github.com/javpower/neutrino-proxy</url>
|
||||
<licenses>
|
||||
<license>
|
||||
@@ -28,7 +29,7 @@
|
||||
</developer>
|
||||
</developers>
|
||||
<properties>
|
||||
<mica-auto.vaersion>2.3.2</mica-auto.vaersion>
|
||||
<mica-auto.version>2.3.2</mica-auto.version>
|
||||
<spring-boot.version>2.7.13</spring-boot.version>
|
||||
<revision>2.0.1</revision>
|
||||
</properties>
|
||||
@@ -67,12 +68,6 @@
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.30</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.dreamlu</groupId>
|
||||
<artifactId>mica-auto</artifactId>
|
||||
<version>${mica-auto.vaersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--SSH中转隧道-->
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
@@ -84,7 +79,12 @@
|
||||
<artifactId>jzlib</artifactId>
|
||||
<version>1.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.dreamlu</groupId>
|
||||
<artifactId>mica-auto</artifactId>
|
||||
<version>${mica-auto.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -116,9 +116,20 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -126,7 +137,7 @@
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<configuration>
|
||||
<mainClass>com.gc.easy.EasyHttpApplication</mainClass>
|
||||
<mainClass>org.dromara.neutrinoproxy.client.starter.SpringProxyClient</mainClass>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@@ -197,5 +208,4 @@
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.dromara.neutrinoproxy.client.starter.ssh;
|
||||
/**
|
||||
*
|
||||
* @author: gc.x
|
||||
* @date: 2024/1/21
|
||||
*/
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// 添加SSH连接
|
||||
String sshId = SSHConnectionFactory.factory.addConnection("194.36.209.398", "root", "xxxxxx", 1234, 6379,"xx.xx.xx.xx");
|
||||
SSHConnectionFactory.factory.openTunnel(sshId);
|
||||
try {
|
||||
Thread.sleep(100000000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 关闭SSH隧道
|
||||
SSHConnectionFactory.factory.closeTunnel(sshId);
|
||||
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package org.dromara.neutrinoproxy.client.starter.util;
|
||||
|
||||
import com.jcraft.jsch.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
/**
|
||||
* 远程发布工具类
|
||||
* @author: gc.x
|
||||
* @date: 2024/1/21
|
||||
*/
|
||||
@Slf4j
|
||||
public class RemoteDeployUtil {
|
||||
|
||||
public static void uploadAndStartJar(List<String> localFilePaths, String remoteDirectory, String remoteStartCommand,
|
||||
String remoteUsername, String remoteHost, String remotePassword) {
|
||||
log.info("Start=================");
|
||||
JSch jsch = new JSch();
|
||||
Session session = null;
|
||||
ChannelSftp channelSftp = null;
|
||||
try {
|
||||
session = jsch.getSession(remoteUsername, remoteHost, 22);
|
||||
session.setPassword(remotePassword);
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
session.connect();
|
||||
channelSftp = (ChannelSftp) session.openChannel("sftp");
|
||||
channelSftp.connect();
|
||||
// 创建远程目录(如果不存在)
|
||||
try {
|
||||
channelSftp.cd(remoteDirectory);
|
||||
} catch (SftpException e) {
|
||||
channelSftp.mkdir(remoteDirectory);
|
||||
channelSftp.cd(remoteDirectory);
|
||||
}
|
||||
// 上传本地文件到远程服务器指定目录
|
||||
for (String localFilePath : localFilePaths) {
|
||||
uploadFileWithProgress(channelSftp, localFilePath, remoteDirectory);
|
||||
}
|
||||
channelSftp.disconnect();
|
||||
// 执行远程命令启动jar包
|
||||
log.info("Command:"+remoteStartCommand);
|
||||
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
|
||||
channelExec.setCommand(remoteStartCommand);
|
||||
ByteArrayOutputStream commandOutput = new ByteArrayOutputStream();
|
||||
channelExec.setOutputStream(commandOutput);
|
||||
channelExec.connect();
|
||||
// 使用新线程读取并打印命令输出
|
||||
Thread outputThread = new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(channelExec.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
outputThread.start();
|
||||
// 等待命令执行完成
|
||||
while (!channelExec.isClosed()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
// 等待命令输出线程结束
|
||||
outputThread.join();
|
||||
channelExec.disconnect();
|
||||
log.info("=================End");
|
||||
} catch (JSchException | SftpException | InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (channelSftp != null) {
|
||||
channelSftp.disconnect();
|
||||
}
|
||||
if (session != null) {
|
||||
session.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void uploadFileWithProgress(ChannelSftp channelSftp, String localFilePath, String remoteDirectory) throws SftpException, IOException {
|
||||
File file = new File(localFilePath);
|
||||
String fileName = file.getName();
|
||||
String remoteFilePath = remoteDirectory + File.separator + fileName;
|
||||
AtomicLong uploadedSize = new AtomicLong();
|
||||
try (InputStream inputStream = new FileInputStream(file)) {
|
||||
// 如果远程目录已经存在同名文件,则先备份原文件
|
||||
if (fileExists(channelSftp, remoteFilePath)) {
|
||||
backupRemoteFile(channelSftp, remoteFilePath);
|
||||
}
|
||||
channelSftp.put(inputStream, remoteFilePath, new SftpProgressMonitor() {
|
||||
@Override
|
||||
public void init(int op, String src, String dest, long max) {
|
||||
// 初始化回调函数,可以做一些准备工作
|
||||
}
|
||||
@Override
|
||||
public void end() {
|
||||
// 上传结束回调函数,可以做一些清理工作
|
||||
}
|
||||
@Override
|
||||
public boolean count(long count) {
|
||||
uploadedSize.addAndGet(count);
|
||||
// 计算上传进度
|
||||
int progress = (int) ((uploadedSize.get() * 100) / file.length());
|
||||
|
||||
// 每上传 10% 显示一次进度,可根据实际情况调整
|
||||
if (progress % 10 == 0) {
|
||||
log.info(fileName+"-----Upload progress: " + progress + "%");
|
||||
}
|
||||
// 返回 true 则继续传输,否则中止传输
|
||||
return true;
|
||||
}
|
||||
}, ChannelSftp.RESUME);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean fileExists(ChannelSftp channelSftp, String remoteFilePath) {
|
||||
try {
|
||||
channelSftp.lstat(remoteFilePath);
|
||||
return true;
|
||||
} catch (SftpException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void backupRemoteFile(ChannelSftp channelSftp, String remoteFilePath) throws SftpException {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||
String backupTime = now.format(formatter);
|
||||
String backupFilePath = remoteFilePath + "." + backupTime;
|
||||
channelSftp.rename(remoteFilePath, backupFilePath);
|
||||
log.info("Remote file already exists. Backing up the original file as: " + backupFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package org.dromara.neutrinoproxy.client.starter.util;
|
||||
|
||||
import com.jcraft.jsch.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Scanner;
|
||||
/**
|
||||
* 简易ssh客户端
|
||||
* @author: gc.x
|
||||
* @date: 2024/1/21
|
||||
*/
|
||||
public class SSHClient {
|
||||
|
||||
private static final String COMMAND_UPLOAD = "upload";
|
||||
private Session session;
|
||||
|
||||
public void connect(String remoteHost, String remoteUsername, String remotePassword) {
|
||||
JSch jsch = new JSch();
|
||||
try {
|
||||
session = jsch.getSession(remoteUsername, remoteHost, 22);
|
||||
session.setPassword(remotePassword);
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
session.connect();
|
||||
System.out.println("Connected to " + remoteHost);
|
||||
} catch (JSchException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void startShell() {
|
||||
if (session == null || !session.isConnected()) {
|
||||
System.out.println("Not connected to a remote host");
|
||||
return;
|
||||
}
|
||||
Channel channel;
|
||||
try {
|
||||
channel = session.openChannel("shell");
|
||||
channel.connect();
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String line;
|
||||
while (true) {
|
||||
System.out.print("$ ");
|
||||
line = scanner.nextLine();
|
||||
if (line.equals("exit")) {
|
||||
break;
|
||||
} else if (line.startsWith(COMMAND_UPLOAD)) {
|
||||
processUploadCommand(line);
|
||||
} else {
|
||||
System.out.println("Executing command: " + line);
|
||||
executeCommand(line);
|
||||
}
|
||||
}
|
||||
} catch (JSchException e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (session != null && session.isConnected()) {
|
||||
session.disconnect();
|
||||
System.out.println("Disconnected from remote host");
|
||||
}
|
||||
}
|
||||
|
||||
private void processUploadCommand(String command) {
|
||||
String[] parts = command.split("\\s+");
|
||||
if (parts.length < 3) {
|
||||
System.out.println("Invalid upload command");
|
||||
return;
|
||||
}
|
||||
String localFilePath = parts[1];
|
||||
String remoteDirectory = parts[2];
|
||||
String remoteFilename = Paths.get(localFilePath).getFileName().toString();
|
||||
if (parts.length >= 4) {
|
||||
remoteFilename = parts[3];
|
||||
}
|
||||
uploadFile(localFilePath, remoteDirectory, remoteFilename);
|
||||
}
|
||||
|
||||
private void uploadFile(String localFilePath, String remoteDirectory, String remoteFilename) {
|
||||
ChannelSftp channelSftp = null;
|
||||
try {
|
||||
channelSftp = (ChannelSftp) session.openChannel("sftp");
|
||||
channelSftp.connect();
|
||||
channelSftp.cd(remoteDirectory);
|
||||
System.out.println("Uploading file: " + localFilePath + " to: " + remoteDirectory + "/" + remoteFilename);
|
||||
channelSftp.put(localFilePath, remoteFilename);
|
||||
System.out.println("File uploaded successfully");
|
||||
} catch (JSchException | SftpException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (channelSftp != null) {
|
||||
channelSftp.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void executeCommand(String command) {
|
||||
ChannelExec channelExec = null;
|
||||
|
||||
try {
|
||||
channelExec = (ChannelExec) session.openChannel("exec");
|
||||
channelExec.setCommand(command);
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
|
||||
channelExec.connect();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
channelExec.disconnect();
|
||||
} catch (JSchException | IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (channelExec != null) {
|
||||
channelExec.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user