上传新构建的jar包到服务器,很好用,记录
工具类:Upload.java
import com.jcraft.jsch.*; import org.apache.commons.lang3.StringUtils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.Calendar; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.concurrent.*; /** * @Description 扫描本地项目中新打的jar包,上传到服务器,清理日志,重启服务 * @Author Waria * @Date 2020/7/1 15:55 */ public class Upload { public static Calendar cal = Calendar.getInstance(); //sftp通道 private static ChannelSftp sftp = null; //sshSession链接 private static Session sshSession; //本地工程路径 private static String localDir = ""; //过滤文件线程 public static ExecutorService executorService = Executors.newSingleThreadExecutor(); //是否清理日志 public static boolean clearLog = false; //重启服务 public static boolean reStart_Enms_2 = true; //需要上传的文件 public static ConcurrentMap<String, File> queueFiles = new ConcurrentHashMap(); /** * 静态方法快: * 读取配置文件,根据配置文件中设置的服务器等信息,打开连接 */ static { Properties properties = new Properties(); try { //配置文件 properties.load(new FileInputStream("D:\\conf.properties")); localDir = properties.getProperty("localDir"); //从日历的当前时间中减去多少小时 String subtractHour = properties.getProperty("subtractHour"); cal.add(Calendar.HOUR_OF_DAY, Integer.parseInt(subtractHour)); String port = properties.getProperty("prot"); //获取sshSession 账号-ip-端口 sshSession = new JSch().getSession(properties.getProperty("user"), properties.getProperty("host"), Integer.parseInt(port)); //添加密码 sshSession.setPassword(properties.getProperty("password")); Properties sshConfig = new Properties(); //严格主机密钥检查 sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); //开启sshSession链接 sshSession.connect(); //获取sftp通道 Channel channel = sshSession.openChannel("sftp"); //连接 channel.connect(); sftp = (ChannelSftp) channel; sftp.cd(properties.getProperty("directory")); } catch (Exception e) { System.out.println("获取配置文件失败:"); e.printStackTrace(); } } public static void main(String[] args) { doShell(); //关闭连接 sftp.disconnect(); sshSession.disconnect(); //退出程序 // System.exit(0); } /** * 执行操作 */ public static void doShell() { try { //上传jar包 upload(); if (clearLog) { //清理日志 clearLog(); } if (reStart_Enms_2) { //重启服务 reStart(); } } catch (Exception e) { System.out.println("执行出错:"); e.printStackTrace(); } } /** * @return 服务器上文件名 */ public static void upload() { try { Long start = System.currentTimeMillis(); //遍历需要上传的jar文件,放入内存queueFiles中 filterJar(localDir); //阻塞,等待所有线程执行完成后关闭线程池 executorService.shutdown(); Boolean b = executorService.awaitTermination(1, TimeUnit.MINUTES); long filterJar = System.currentTimeMillis(); System.out.println("遍历jar文件执行完成:" + b + ",耗时:" + (filterJar - start)); if (b) { try { //上传文件 uploadThread(); } catch (Exception e) { System.out.println("上传文件失败:"); e.printStackTrace(); } } System.out.println("文件上传完成,总共耗時:" + (System.currentTimeMillis() - start)); } catch (Exception e) { System.out.println("上文件出错:"); e.printStackTrace(); } } /** * 清除日志 */ private static void clearLog() { Long start = System.currentTimeMillis(); String command = "rm -rf /.../log"; executeShell(command); System.out.println("日志清理完成,耗時:" + (System.currentTimeMillis() - start)); } /** * 重启服务 */ private static void reStart() { Long start = System.currentTimeMillis(); String command = "sh /.../restart.sh"; executeShell(command); //查看服务状态,执行时,可能服务还未启动成功,可休眠一定时间再查询 // Thread.sleep(5000); String com = "sh /.../status.sh"; executeShell(com); System.out.println("服务重启完成,耗時:" + (System.currentTimeMillis() - start)); } /** * 执行脚本 * * @param command * @return */ public static int executeShell(final String command) { int returnCode = -1; try { //创建exec通道 Channel channel = sshSession.openChannel("exec"); ((ChannelExec) channel).setCommand(command); BufferedReader input = new BufferedReader(new InputStreamReader(channel .getInputStream())); channel.connect(); System.out.println("执行脚本: " + command); //获取远程命令的输出。 String line; while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); //仅在通道关闭后获取返回代码。 if (channel.isClosed()) { returnCode = channel.getExitStatus(); } } catch (Exception e) { System.out.println(command + "脚本执行出错:"); e.printStackTrace(); } return returnCode; } /** * 上传文件任务 */ private static void uploadThread() throws InterruptedException { //已上传文件总数 final int[] i = {0}; long start = System.currentTimeMillis(); ExecutorService executorService1 = Executors.newSingleThreadExecutor(); for (Iterator<Map.Entry<String, File>> it = queueFiles.entrySet().iterator(); it.hasNext(); ) { final Map.Entry<String, File> next = it.next(); executorService1.submit(() -> { synchronized (StringUtils.EMPTY) { i[0]++; try { sftp.put(new FileInputStream(next.getValue()), next.getKey(), ChannelSftp.OVERWRITE); } catch (Exception e) { System.out.println(next.getValue().getName() + "文件上传出错:"); e.printStackTrace(); } } }); } executorService1.shutdown(); Boolean b = executorService1.awaitTermination(1, TimeUnit.MINUTES); System.out.println("上传文件任务执行完成:" + b + ",上传文件个数:" + i[0] + ",耗时:" + (System.currentTimeMillis() - start)); } /** * 扫描本地项目路径中的jar文件 * * @param localDir 本地项目路径 */ public static void filterJar(String localDir) { try { final File file = new File(localDir); if (file.isDirectory()) { //文件夹,扫描包含的jar包 final File[] files = file.listFiles(); if (files == null || files.length <= 0) { return; } dealDirectory(files); } else { //文件,直接上传 executorService.submit(() -> wetherJarAndPut(file.getName(), file)); } } catch (Exception e) { System.out.println("扫描本地项目路径出错:"); e.printStackTrace(); } } /** * @param files 遍历所有文件 */ private static void dealDirectory(File[] files) { for (final File f : files) { String fp = f.getAbsolutePath(); try { if (f.isDirectory()) { filterJar(fp); } else { executorService.submit(() -> wetherJarAndPut(f.getName(), f) ); } } catch (Exception e) { System.out.println("遍历目录文件出错:"); e.printStackTrace(); } } } /** * 校验文件是否是jar包,是则放入内存queueFiles * * @param name 文件名 * @param f 文件 */ private static void wetherJarAndPut(String name, File f) { if (name.endsWith(".jar")) { Calendar cal2 = Calendar.getInstance(); cal2.setTimeInMillis(f.lastModified()); //判断文件修改时间,是否为近一个小时 if (cal.after(cal2)) { return; } if (queueFiles.containsKey(name)) { File old = queueFiles.get(name); //文件名相同,使用最近一次更新的文件 if (old.lastModified() < f.lastModified()) { queueFiles.put(name, f); } } else { //新文件直接放入待上传队列 queueFiles.put(name, f); } } } }配置文件:conf.properties
#主机ip host=127.0.0.1 #端口 prot=22 #账号 user=root #密码 password=root #服务器路径 directory=/.../lib #本地工程路径 localDir=D:/workspace/.. #最近1小时内更新的过的jar文件,认为是新文件,单位:小时,负数 subtractHour=-1涉及依赖:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency>