java 整合jsch使用 遠程交互服務器


java 整合jsch使用 遠程交互服務器

java 通過jsch 遠程執行命令 jsch 主要是類似Xshell 只不過是代碼級別使用
而 Xshell使用界面化

jsch可以執行任何shell 腳本 但是弊端是執行一次必須要關閉當前會話 每次都要cd當前目錄
在執行相關命令 都是操作 channle 同時寫了一個cmd執行方法為的是執行linux命令
execCommandByJSch (…) 這個方法是比較重要的 session就是維護你當前會話和服務器進行交流的

channle相當於管道流 數據交互用的

依賴

  <!-- sftp的依賴--> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency> 

這里是以前某個項目的一部分代碼

package com.ubix.infinite.business.maintain.util; import com.alibaba.fastjson.JSON; import com.jcraft.jsch.*; import com.ubix.infinite.business.maintain.constants.MaintainConstants; import com.ubix.infinite.business.maintain.pojo.MaiFtpServer; import com.ubix.infinite.business.maintain.pojo.MaiServerAndPath; import com.ubix.infinite.business.maintain.pojo.MaiServerSoftware; import com.ubix.infinite.business.maintain.task.recoder.SoftwareDbUtils; import com.ubix.infinite.common.core.contexts.SecurityContext; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.util.*; @Slf4j public class Ftp { private static final String ENCODE_UTF_8 = "UTF-8"; private Date lastPushDate = null; private static final String HISTORY_FOLDER = "history_server"; private Session sshSession; private ChannelSftp channel; public Ftp(String host, int port, String username, String password) throws Exception { connection(host, port, username, password); } public Ftp(MaiFtpServer maiFtpServer) throws Exception { String username = maiFtpServer.getUsername(); String password = maiFtpServer.getPassword(); String host = maiFtpServer.getHost(); int port = maiFtpServer.getPort(); connection(host, port, username, password); } /** * 鏈接服務器 * @param host * @param port * @param username * @param password * @throws Exception */ public void connection(String host, int port, String username, String password) throws Exception { JSch jsch = new JSch(); jsch.getSession(username, host, port); //根據用戶名,密碼,端口號獲取session sshSession = jsch.getSession(username, host, port); sshSession.setPassword(password); //修改服務器/etc/ssh/sshd_config 中 GSSAPIAuthentication的值yes為no,解決用戶不能遠程登錄 sshSession.setConfig("userauth.gssapi-with-mic", "no"); //為session對象設置properties,第一次訪問服務器時不用輸入yes sshSession.setConfig("StrictHostKeyChecking", "no"); sshSession.connect(); //獲取sftp通道 channel = (ChannelSftp) sshSession.openChannel("sftp"); channel.connect(); log.info("連接ftp成功!"); } /** * 關閉通道 */ public void closeChannel() { if (null != channel) { try { channel.disconnect(); } catch (Exception e) { log.error("關閉SFTP通道發生異常:", e); } } if (null != sshSession) { try { sshSession.disconnect(); } catch (Exception e) { log.error("SFTP關閉 session異常:", e); } } } /** * @param directory 上傳ftp的目錄 * @param uploadFile 本地文件目錄 * @param isDel 是否刪除原文件 */ public Hashtable<String, Object> upload(String directory, String uploadFile, boolean isDel, MaiFtpServer maiFtpServer) { Hashtable<String, Object> collectionResult = new Hashtable<>(); try { cdDirectory(directory); collectionResult = toUpload(directory, uploadFile, isDel, maiFtpServer); } catch (Exception e) { log.info("上傳失敗"); } return collectionResult; } /** * 根據當前路徑獲取目錄文件 * @param directory * @return */ public String getSonDirectory(String directory) { String dir = directory.substring(0, directory.lastIndexOf("/") + 1); try { channel.cd(dir); } catch (SftpException e) { log.error(e.getMessage()); } return "true"; } /** * 獲取文件夾下的文件 * * @param directory 路徑 */ public Vector<?> listFiles(String directory) { try { if (isDirExist(directory)) { Vector<?> vector = channel.ls(directory); //移除上級目錄和根目錄:"." ".." vector.remove(0); vector.remove(0); return vector; } } catch (SftpException e) { log.error("獲取文件夾信息異常!", e); } return null; } /** * 判斷目錄是否存在 * * @param directory 路徑 */ public boolean isDirExist(String directory) { boolean isDirExistFlag = false; try { SftpATTRS sftpATTRS = channel.lstat(directory); isDirExistFlag = true; return sftpATTRS.isDir(); } catch (Exception e) { if ("no such file".equals(e.getMessage())) { isDirExistFlag = false; } } return isDirExistFlag; } /** * 進入該路徑 * @param directory * @throws SftpException */ public void cdDirectory(String directory) throws SftpException { String[] directories = directory.split("/"); for (int i = 0; i < directories.length; i++) { String d = directories[i]; if (StringUtils.isBlank(d)) { continue; } try { if (i == 1) { channel.cd("/" + d); continue; } channel.cd(d); } catch (Exception e) { channel.mkdir(d); channel.cd(d); } } } /** * 遍歷該路徑的shell腳本並啟動或停止 * @param directory * @param maiFtpServer * @param operator * @return */ public Hashtable<String, Object> queryShAndOperator(String directory, MaiFtpServer maiFtpServer, String operator) { Hashtable<String, Object> hashtable = new Hashtable<>(); Vector ls = null; try { ls = channel.ls(directory); } catch (SftpException e) { log.error(e.getMessage()); } Iterator iterator = ls.iterator(); String result = "空"; while (iterator.hasNext()) { ChannelSftp.LsEntry next = (ChannelSftp.LsEntry) iterator.next(); String filename = next.getFilename(); if (filename.contains(".sh")) { hashtable = startUpSh(directory, filename, maiFtpServer, operator, ""); log.info(" the {} ,the result: {}", filename, result); } } return hashtable; } /** * 上傳文件,解壓,遍歷並且啟動 * @param directory * @param uploadFile * @param isDel * @param maiFtpServer * @return */ public Hashtable<String, Object> toUpload(String directory, String uploadFile, boolean isDel, MaiFtpServer maiFtpServer) { Set<String> fileNames = new HashSet<>(); Hashtable<String, Object> resultHashTable = new Hashtable<>(); //上傳文件 try { List<File> files = getFiles(uploadFile, new ArrayList<>()); for (int i = 0; i < files.size(); i++) { File file = files.get(i); InputStream input = new BufferedInputStream(new FileInputStream(file)); channel.put(input, file.getName()); fileNames.add(file.getName()); try { input.close(); } catch (Exception e) { log.error(e.getMessage()); log.error("{} close the file is error {}", file.getName(), e.getMessage()); } if (file.exists() && isDel) { boolean b = file.delete(); log.info("{} the file is upload success! {}", file.getName(), b); } } for (File file : files) { String fileName = file.getName(); //zip解壓 if (fileName.contains(".zip")) { cdAndExecCmd(directory, fileName, "unzip " + fileName); } if (!fileName.contains(".sh")) { continue; } log.info("嘗試啟動 {} 腳本", fileName); // 如果上傳文件集合里面包含.sh為后綴的文件 嘗試啟動它 Hashtable<String, Object> hashtable = startUpSh(directory, fileName, maiFtpServer, "start", uploadFile); resultHashTable.put(hashtable.get(MaintainConstants.FILE_NAME).toString(), hashtable.get(MaintainConstants.LOG).toString()); } if (directory.contains("gcc")||directory.contains("redis")||directory.contains("mysql")||directory.contains("nacos")){ return resultHashTable; } //獲取解壓后的所有啟動文件以及所在路徑 Set<String> unZipSonDirectorySet = lsDirectory(directory); Map<String, String> startUpMap = cdUnKnownDirectory(unZipSonDirectorySet, directory); //啟動這些服務 Hashtable<String, Object> hashtable = startServerMap(startUpMap, maiFtpServer); if (StringUtils.isNotBlank(maiFtpServer.getHost())){ hashtable.put(MaintainConstants.HOST, maiFtpServer.getHost()); } resultHashTable.putAll(hashtable); } catch (Exception e) { log.info("upload the files is error!!", e); } return resultHashTable; } /** * 遍歷map集合的文件並且啟動 * @param startUpMap * @param maiFtpServer * @return */ private Hashtable<String, Object> startServerMap(Map<String, String> startUpMap, MaiFtpServer maiFtpServer) { Hashtable<String, Object> hashtable = new Hashtable<>(); Hashtable<String, Object> h; if (startUpMap.isEmpty()) { return null; } for (String s : startUpMap.keySet()) { try { h = startUpServer(s, maiFtpServer); hashtable.putAll(h); } catch (IOException e) { log.error("start the {} is error!!", startUpMap.get(s)); } } return hashtable; } /** * 查找當前路徑下所有.sh的文件以及所在路徑 * * @param directorySet * @param basePath */ Map<String, String> cdUnKnownDirectory(Set<String> directorySet, String basePath) { Map<String, String> map = new HashMap<>(); for (String directory : directorySet) { String path = basePath + directory + "/"; try { channel.cd(path); } catch (SftpException e) { log.error("{} is not directory!! ", directory); if (directory.contains(".sh")) { log.info("try start up the {}", directory); map.put(basePath, directory); continue; } } //歷史版本不啟動 if (directory.contains(HISTORY_FOLDER)) { continue; } Set<String> set = lsDirectory(path); if (CollectionUtils.isEmpty(set)) { continue; } map.putAll(cdUnKnownDirectory(set, path)); } return map; } /** * 列出本目錄所有的文件和子目錄 * * @param directory * @return Set<String> */ public Set<String> lsDirectory(String directory) { Set<String> set = new HashSet<>(); Vector ls = null; try { ls = channel.ls(directory); } catch (SftpException e) { log.error("the {} is not directory!!", directory); } if (ls == null) { return null; } Iterator iterator = ls.iterator(); while (iterator.hasNext()) { ChannelSftp.LsEntry next = (ChannelSftp.LsEntry) iterator.next(); String filename = next.getFilename(); if (filename.startsWith(".")) { continue; } set.add(filename); } return set; } /** * 對某個文件執行命令 * @param directory * @param fileName * @param cmd * @return * */ public String cdAndExecCmd(String directory, String fileName, String cmd) { String tryStartUpShCmd = "cd " + directory + " && " + cmd; String execute = execCommandByJSch(tryStartUpShCmd); log.info("startup " + fileName + " result:" + execute); return execute; } /** * 運行shell腳本 * @param directory * @param fileName * @param maiFtpServer * @param operator * @param uploadFile * @return */ public Hashtable<String, Object> startUpSh(String directory, String fileName, MaiFtpServer maiFtpServer, String operator, String uploadFile) { Hashtable<String, Object> hashtable = new Hashtable<>(); String tryStartUpShCmd = "cd " + directory + "&& sed -i 's/\\r//' " + fileName; execCommandByJSch(tryStartUpShCmd); String execute ; String tryStartUpShCmd2 = "cd " + directory + " && sh " + fileName + " " + operator; execute = execCommandByJSch(tryStartUpShCmd2); MaiServerSoftware maiServerSoftware = new MaiServerSoftware(); maiServerSoftware.setIp(maiFtpServer.getHost()); maiServerSoftware.setTargetPath(directory); maiServerSoftware.setCreateBy(SecurityContext.getUsername()); maiServerSoftware.setOperate(operator); execute = execute.replaceAll("\r\n|\n", ""); if (execute.length() < 70) { maiServerSoftware.setLog(execute); } else { maiServerSoftware.setLog(execute.substring(0, 50)); } log.info(" the result:" + execute); maiServerSoftware.setServerId(maiFtpServer.getHost()); maiServerSoftware.setServiceName(fileName); maiServerSoftware.setSrcPath(uploadFile); if (execute.contains(MaintainConstants.SUCCESS)) { maiServerSoftware.setStatus(true); } SoftwareDbUtils ftpOperate = new SoftwareDbUtils(); //保存操作記錄 if (ftpOperate.save(maiServerSoftware)) { log.info("save the {} is success!!", JSON.toJSON(maiServerSoftware)); } else { log.error("save the {} is error!!", JSON.toJSON(maiServerSoftware)); } log.info("startup " + fileName + " result:" + execute); hashtable.put(MaintainConstants.FILE_NAME, maiServerSoftware.getServiceName()); hashtable.put(MaintainConstants.LOG, execute); return hashtable; } /** * 獲取本地某路徑下文件 * @param realpath * @param files * @return */ public List<File> getFiles(String realpath, List<File> files) { File realFile = new File(realpath); if (realFile.isDirectory()) { File[] subfields = realFile.listFiles(new FileFilter() { @Override public boolean accept(File file) { if (null == lastPushDate) { return true; } else { long modifyDate = file.lastModified(); return modifyDate > lastPushDate.getTime(); } } }); if (subfields.length==0){ return files; } for (File file : subfields) { if (file.isDirectory()) { getFiles(file.getAbsolutePath(), files); } else { files.add(file); } } } else { files.add(realFile); } return files; } /** * 查詢該路徑下的shell並開啟服務 * @param directory * @param maiFtpServer * @return */ public Hashtable<String, Object> startUpServerToFtp(String directory, MaiFtpServer maiFtpServer) { Hashtable<String, Object> startServerResult = new Hashtable<>(); //先停止服務 try { startServerResult = startUpServer(directory, maiFtpServer); } catch (IOException e) { log.error(e.getMessage()); } return startServerResult; } /** * 查找歷史文件 * @param directory */ public void mkdirHistory(String directory) { // 查找歷史文件名 查找出來進行備份 String getFilesCmd = "cd " + directory + "; mkdir history_server"; execCommandByJSch(getFilesCmd); } /** * 移動文件 * @param directory * @param targetPath * @param fileNamePrefix */ public void mv(String directory, String targetPath, String fileNamePrefix) { if (!StringUtils.isBlank(fileNamePrefix)) { fileNamePrefix = "./" + fileNamePrefix + "*"; } else { fileNamePrefix = "*"; } // 查找歷史文件名 查找出來進行備份 String getFilesCmd = "cd " + directory + "&& mv " + fileNamePrefix + " " + targetPath; execCommandByJSch(getFilesCmd); } /** * 刪除文件 */ public void deleteFile(String directory) { String tryStartUpShCmd2 = "rm -rf " + directory; execCommandByJSch(tryStartUpShCmd2); } /** * 移動文件到歷史文件夾里面 * @param maiServerAndPath */ public void moveFileToHistory(MaiServerAndPath maiServerAndPath) { String directory = maiServerAndPath.getDirectory(); mkdirHistory(directory); mv(directory, HISTORY_FOLDER, null); } /** * exec 執行ssh命令 * @param command * @return */ public String execCommandByJSch(String command) { //1.默認方式,執行單句命令 InputStream in; String result = null; try { ChannelExec channelExec = (ChannelExec) sshSession.openChannel("exec"); in = channelExec.getInputStream(); channelExec.setCommand(command); channelExec.setErrStream(System.err); channelExec.connect(); result = IOUtils.toString(in, ENCODE_UTF_8); channelExec.disconnect(); } catch (Exception e) { log.error(e.getMessage()); } return result; } /** * 啟動服務 * @param directory * @param maiFtpServer * @return * @throws IOException */ private Hashtable<String, Object> startUpServer(String directory, MaiFtpServer maiFtpServer) throws IOException { return queryShAndOperator(directory, maiFtpServer, "start"); } /** * 停止服務 * @param maiServerAndPath * @return */ public Hashtable<String, Object> stopServer(MaiServerAndPath maiServerAndPath) { Hashtable<String, Object> executeResult = queryShAndOperator(maiServerAndPath.getDirectory(), maiServerAndPath.getMaiFtpServer(), "stop"); return executeResult; } /** * 移動history_server某個文件到當前 * @param directory * @param fileName */ public void mvToCurrent(String directory, String fileName) { mv(directory, HISTORY_FOLDER, null); mv(directory + "/" + HISTORY_FOLDER, "../", fileName); } } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM