From dd1c65f2e4edd09110a91812ca59326be64f311b Mon Sep 17 00:00:00 2001 From: xgc Date: Fri, 26 Jan 2024 13:25:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?starter=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/starter/util/RemoteDeployUtil.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java new file mode 100644 index 00000000..380ca75b --- /dev/null +++ b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/RemoteDeployUtil.java @@ -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 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); + } +} + + + From 641e3533ea1a5fb21ac951fe8d8e3bb325ca7c0e Mon Sep 17 00:00:00 2001 From: xgc Date: Fri, 26 Jan 2024 14:13:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?starter=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/starter/util/SSHClient.java | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java new file mode 100644 index 00000000..aad352dc --- /dev/null +++ b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/util/SSHClient.java @@ -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(); + } + } + } +} From d996cf096eac56d3a0f96d3f710a3cc3e6ab899e Mon Sep 17 00:00:00 2001 From: xgc Date: Fri, 26 Jan 2024 15:30:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9starter=E6=89=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../neutrino-proxy-client-starter/Dockerfile | 2 +- client+/neutrino-proxy-client-starter/pom.xml | 40 +++++++++++------- .../client/starter/ssh/Test.java | 22 ---------- .../src/main/resources/test.jks | Bin 1388 -> 0 bytes 4 files changed, 26 insertions(+), 38 deletions(-) delete mode 100644 client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java diff --git a/client+/neutrino-proxy-client-starter/Dockerfile b/client+/neutrino-proxy-client-starter/Dockerfile index e2a41943..bfa84f56 100644 --- a/client+/neutrino-proxy-client-starter/Dockerfile +++ b/client+/neutrino-proxy-client-starter/Dockerfile @@ -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"] diff --git a/client+/neutrino-proxy-client-starter/pom.xml b/client+/neutrino-proxy-client-starter/pom.xml index 9c2a34ba..ae6e3488 100644 --- a/client+/neutrino-proxy-client-starter/pom.xml +++ b/client+/neutrino-proxy-client-starter/pom.xml @@ -4,8 +4,9 @@ 4.0.0 io.github.javpower neutrino-proxy-client-spring-boot-starter - ${revision} - jar + 2.0.1 + neutrino-proxy-client-spring-boot-starter + a tool about easy neutrino-proxy-client https://github.com/javpower/neutrino-proxy @@ -28,7 +29,7 @@ - 2.3.2 + 2.3.2 2.7.13 2.0.1 @@ -67,12 +68,6 @@ lombok 1.18.30 - - net.dreamlu - mica-auto - ${mica-auto.vaersion} - provided - com.jcraft @@ -84,7 +79,12 @@ jzlib 1.1.3 - + + net.dreamlu + mica-auto + ${mica-auto.version} + provided + @@ -116,9 +116,20 @@ maven-compiler-plugin 3.8.1 - 21 - 21 - UTF-8 + 8 + 8 + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + true + + @@ -126,7 +137,7 @@ spring-boot-maven-plugin ${spring-boot.version} - com.gc.easy.EasyHttpApplication + org.dromara.neutrinoproxy.client.starter.SpringProxyClient true @@ -197,5 +208,4 @@ - diff --git a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java b/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java deleted file mode 100644 index 6ef517de..00000000 --- a/client+/neutrino-proxy-client-starter/src/main/java/org/dromara/neutrinoproxy/client/starter/ssh/Test.java +++ /dev/null @@ -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); - - } -} diff --git a/client+/neutrino-proxy-client-starter/src/main/resources/test.jks b/client+/neutrino-proxy-client-starter/src/main/resources/test.jks index 3a4d1ad89e1a538f35c3b2996b2241d465ddedad..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 1388 zcmezO_TO6u1_mY|W&~rN#Nzbi;^Lf=)Z!9DpkSlVC1(Smg53s9Oxq3k*toRW7+Dy# zm;@OaSs7TGm=?c3uQzq2R{u|yvt1m9yKNY51-F}KEJ}Vg&o%pt^a}sGfvLwnY29Gd zTK;ObR&0Uur4M;;GlS;#-gw>e_e9sjrFAU2jh#`x$0uYu?)VbdCRlQ;cbop#2hGK= ziyy2KJ)QF9`=T?|dPT+u;&T-HqqpXzeZ1Z;XvAW7?@w^7din<*!I_J#87{mRYhpFg z@10k1i)D8CPu+uI?f*lb3r_A`$5e44A#U5J9|1W>CN7u}_~lBo{fzJ1IL%&NU}<<@ z)V5RUV4@=b#-E8d!w;I?vHr&+aeRy5o2%mfvpOZ$tUL2=>Dq(Id<=a@GJI<6S5H4u znXcaTzss0K{no9IXN%k}NJdS5VmIZ|CVq(%7xkDWSNI2s*L3>c6XI2Qnk3%4xN7-Z z58Kt}*`GbsV867(r#9b5I?Mg%X4$%9wtrgW+e`}+Z6>$Y%)7nFiZNR81w$Cu_AqJb zzqyy!eHU5z`gxZ54>#VWPmcX@Kf_vD9oC%ove36y^O4cD+_1&y;RvIo@|$6)$zqXeQT_l?H8kLAw$r zW&M}^;8?ul=EW1DugazGOx|!dyk>gn(nEVXFF&u44!K+@p_`SSd3O6zjd|~vuP@Eo zy6e1E!t3PCp*e@H-@KvjCZD_N^S!@nri)hSm3uGuJ3nz&&gnN_*k`dPIdv?mE2<0) z56!D}6o2z@sq%h~hv(ulYQmY{DQ6#_`&EQZq|NmC&$fu4C+AjmZ+#GX^7=XZ1V5*` zm6c};Rx>@_RU~_-Y|8n6#)379wv)A$HviU1z3}*UbKtfqO~zM`OX=UypC-e+wJ?>- z;AcTcx$N;XYo=LxTh7|MHchRL>>MUXhuXmYSCi6X8aP@EUM~ z)G!OPR3_%78_0?C8W|aw85$T^n3@=xM~U+q1Gxs~P%eEO(KsL3@4!6G+}O)t(Ade; z*vN3L^6OR^0Yd^Q#lYBs__SiYmr~JCS z&z|e7)OnIFx8r=dQti~DZH^%(Dwy0jzrma7_ z+b`we=F3O6^6gRblG-}2vnTF(*1Cxb^(}4nPC0Sk=Q1%fGB7SyG>|ut1%{g}ABz}^ zNV)8t_!eH_w&B5RX^O|dbLmff|Ae|f#!{yG!~gS3T7CXD&12I zwcEQW@#FDqN5Xx ioku-b)|M>LROU)QG0ot&TE@jEVVOmyMi>7@Z~y={B|CNi