java實(shí)現(xiàn)服務(wù)器巡查的代碼
需求
用戶,給了一大批服務(wù)器,需要檢查服務(wù)器能否ping通,ssh密碼是否正常,以及檢查服務(wù)器的cpu,內(nèi)存,硬盤占用情況。一個(gè)個(gè)檢查肯定不現(xiàn)實(shí),于是希望通過代碼實(shí)現(xiàn)。
批量ping
1.Jdk1.5的InetAddresss方式
注意:使用時(shí)應(yīng)注意,如果遠(yuǎn)程服務(wù)器設(shè)置了防火墻或相關(guān)的配制,可能會(huì)影響到結(jié)果。另外,由于發(fā)送ICMP請(qǐng)求需要程序?qū)ο到y(tǒng)有一定的權(quán)限,當(dāng)這個(gè)權(quán)限無(wú)法滿足時(shí), isReachable方法將試著連接遠(yuǎn)程主機(jī)的TCP端口??赡艹霈F(xiàn)isReachable=false但是用cmd驗(yàn)證卻能夠ping通的情況。
代碼實(shí)現(xiàn):
/** * 這個(gè)不可行,和ping的結(jié)果并不完全一致 盡量別用 * @param ip * @return */ public static boolean netOk(String ip){ InetAddress address=null; boolean netOk=false; try { address =InetAddress.getByName(ip); netOk= address.isReachable(5000); } catch (Exception e) { e.printStackTrace(); } return netOk; }
2.最簡(jiǎn)單的辦法,直接調(diào)用CMD
注意:如果出現(xiàn)Windows環(huán)境下可以正常ping通的,而在centOS(Linux)里面無(wú)法ping通,可能是被ping的設(shè)備上有設(shè)置ping包大小限制,限制在了32位以內(nèi)。
最終使用
Process pro = Runtime.getRuntime().exec("ping -s 32 " + ipAddress );
并解析結(jié)果來進(jìn)行判斷。
命令行基礎(chǔ)
其中n是次數(shù),w是超時(shí)時(shí)間,單位是毫秒
ping -n 1 -w 1000 9.8.8.8
代碼實(shí)現(xiàn):
/** * * @param ipAddress * @param pingTimes 單位是毫秒 * @param timeOut * @return */ public static boolean ping(String ipAddress, int pingTimes, int timeOut) { BufferedReader in = null; Runtime r = Runtime.getRuntime(); // 將要執(zhí)行的ping命令,此命令是windows格式的命令 String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut; try { // 執(zhí)行命令并獲取輸出 System.out.println(pingCommand); Process p = r.exec(pingCommand); if (p == null) { return false; } in = new BufferedReader( new InputStreamReader(p.getInputStream())); // 逐行檢查輸出,計(jì)算類似出現(xiàn)=23ms TTL=62字樣的次數(shù) int connectedCount = 0; String line = null; while ((line = in.readLine()) != null) { connectedCount += getCheckResult(line); } // 如果出現(xiàn)類似=23ms TTL=62這樣的字樣,出現(xiàn)的次數(shù)=測(cè)試次數(shù)則返回真 return connectedCount == pingTimes; } catch (Exception ex) { ex.printStackTrace(); // 出現(xiàn)異常則返回假 return false; } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } // 若line含有=18ms TTL=16字樣,說明已經(jīng)ping通,返回1,否則返回0. private static int getCheckResult(String line) { // System.out.println("控制臺(tái)輸出的結(jié)果為:"+line); Pattern pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(line); while (matcher.find()) { return 1; } return 0; }
3.Java調(diào)用shell執(zhí)行ping命令
注意:這種需要在linux環(huán)境執(zhí)行
命令行基礎(chǔ)
其中 -c是次數(shù),-W是超時(shí)時(shí)間,單位是秒
ping -c 2 -W 1 8.8.8.8
/** * * @param ipAddress * @param pingTimes * @param timeOut 單位 s * @return */ public static boolean pingByShell(String ipAddress, int pingTimes, int timeOut){ String sh="ping -c "+pingTimes+" -W "+timeOut+" "+ipAddress; String result = exeShell(sh); if(result!=null){ if(result.contains("ttl")){ return true; } } return false; } /** * 執(zhí)行shell并且返回結(jié)果 * @param sh * @return */ public static String exeShell(String sh){ Process process = null; List<String> processList = new ArrayList<String>(); try { process = Runtime.getRuntime().exec(sh); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { processList.add(line); } input.close(); } catch (IOException e) { e.printStackTrace(); return null; } String result = StringUtils.join(processList, "\n"); return result; }
批量ssh檢查
需求:
先檢查網(wǎng)絡(luò)是否通(這里我是先檢查ssh用的22端口),不通的記錄下來,端口通的,再用文檔記錄的登錄信息ssh登錄,將登錄成功的和不成功的分別記錄下來。
注意:有的服務(wù)器有安全策略,不要同一臺(tái)服務(wù)器多次嘗試。
依賴引入
<!-- ssh --> <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency>
工具封裝
package com.isi.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Calendar; import org.apache.commons.lang3.StringUtils; import ch.ethz.ssh2.Connection; import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; public class SshUtil { private static String DEFAULT_CHAR_SET = "UTF-8"; private static String tipStr = "=======================%s======================="; private static String splitStr = "====================================================="; /** * 登錄主機(jī) * @return * 登錄成功返回true,否則返回false */ public static Connection login(String ip, String userName, String password){ boolean isAuthenticated = false; Connection conn = null; long startTime = Calendar.getInstance().getTimeInMillis(); try { conn = new Connection(ip); conn.connect(); // 連接主機(jī) isAuthenticated = conn.authenticateWithPassword(userName, password); // 認(rèn)證 if(isAuthenticated){ System.out.println(String.format(tipStr, "認(rèn)證成功")); } else { System.out.println(String.format(tipStr, "認(rèn)證失敗")); } } catch (IOException e) { System.err.println(String.format(tipStr, "登錄失敗")); e.printStackTrace(); } long endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("登錄用時(shí): " + (endTime - startTime)/1000.0 + "s\n" + splitStr); return conn; } public static boolean pwdCheck(String ip, String userName, String password){ boolean isAuthenticated = false; Connection conn = null; long startTime = Calendar.getInstance().getTimeInMillis(); try { conn = new Connection(ip); conn.connect(); // 連接主機(jī) isAuthenticated = conn.authenticateWithPassword(userName, password); // 認(rèn)證 if(isAuthenticated){ System.out.println(String.format(tipStr, "認(rèn)證成功")); return true; } else { System.out.println(String.format(tipStr, "認(rèn)證失敗")); return false; } } catch (Exception e) { System.err.println(String.format(tipStr, "登錄失敗")); e.printStackTrace(); }finally { if(conn!=null){ conn.close(); } } long endTime = Calendar.getInstance().getTimeInMillis(); System.out.println("登錄用時(shí): " + (endTime - startTime)/1000.0 + "s\n" + splitStr); return false; } /** * 遠(yuǎn)程執(zhí)行shell腳本或者命令 * @param cmd * 即將執(zhí)行的命令 * @return * 命令執(zhí)行完后返回的結(jié)果值 */ public static String execute(Connection conn, String cmd){ String result = ""; Session session = null; try { if(conn != null){ session = conn.openSession(); // 打開一個(gè)會(huì)話 session.execCommand(cmd); // 執(zhí)行命令 result = processStdout(session.getStdout(), DEFAULT_CHAR_SET); //如果為得到標(biāo)準(zhǔn)輸出為空,說明腳本執(zhí)行出錯(cuò)了 if(StringUtils.isBlank(result)){ System.err.println("【得到標(biāo)準(zhǔn)輸出為空】\n執(zhí)行的命令如下:\n" + cmd); result = processStdout(session.getStderr(), DEFAULT_CHAR_SET); }else{ System.out.println("【執(zhí)行命令成功】\n執(zhí)行的命令如下:\n" + cmd); } } } catch (IOException e) { System.err.println("【執(zhí)行命令失敗】\n執(zhí)行的命令如下:\n" + cmd + "\n" + e.getMessage()); e.printStackTrace(); } finally { if (conn != null) { conn.close(); } if (session != null) { session.close(); } } return result; } /** * 解析腳本執(zhí)行返回的結(jié)果集 * @param in 輸入流對(duì)象 * @param charset 編碼 * @return * 以純文本的格式返回 */ private static String processStdout(InputStream in, String charset){ InputStream stdout = new StreamGobbler(in); StringBuffer buffer = new StringBuffer(); try { BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset)); String line = null; while((line = br.readLine()) != null){ buffer.append(line + "\n"); } } catch (UnsupportedEncodingException e) { System.err.println("解析腳本出錯(cuò):" + e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.err.println("解析腳本出錯(cuò):" + e.getMessage()); e.printStackTrace(); } return buffer.toString(); } /** * 判斷端口是否通 * @param host * @param port * @param timeout * @return */ public static boolean isHostConnectable(String host, int port,int timeout) { Socket socket = new Socket(); try { socket.connect(new InetSocketAddress(host, port),timeout); socket.setSoTimeout(timeout); } catch (IOException e) { e.printStackTrace(); return false; } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } return true; } }
密碼核對(duì)
public static void main(String[] args){ String ip = "192.168.4.188"; // 此處根據(jù)實(shí)際情況,換成自己需要訪問的主機(jī)IP String userName = "root"; String password = "123456"; boolean flag = pwdCheck(ip, userName, password); System.out.println("flag===="+flag); }
資源巡查
使用封裝的sshUtil
public static void main(String[] args){ // 此處根據(jù)實(shí)際情況,換成自己需要訪問的主機(jī)IP String ip = "192.168.4.188"; String userName = "root"; String password = "123456"; /* boolean flag = pwdCheck(ip, userName, password); System.out.println("flag===="+flag);*/ Connection connection = login(ip, userName, password); //查看最大的盤 指定---為分隔符,默認(rèn)的分隔符java無(wú)法指定 String max_disk_cmd="df | sort -k2nr | head -1 | awk '{print $2,$3,$4,$5}' OFS='---' "; //查看內(nèi)存使用情況 String free_mem_cmd="free | sort -k2nr | head -1 | awk '{print $2,$3,$4}' OFS='---'"; //計(jì)算cpu使用率, -n number:指定在結(jié)束前應(yīng)該產(chǎn)生的最大迭代次數(shù)或幀數(shù),一般迭代次數(shù)越大,獲取到的cpu使用率越準(zhǔn)確; 本腳本中是迭代了5次,"-n5" String cpu_use_cmd="top -b -n5 | fgrep \"Cpu(s)\" | tail -1 | awk -F'id,' '{split($1, vs, \",\"); v=vs[length(vs)]; sub(/\\s+/, \"\", v);sub(/\\s+/, \"\", v); printf \"%d\", 100-v;}'"; String result = execute(connection, cpu_use_cmd); System.out.println("result = " + result); String[] datas = result.split("---"); String str = Arrays.toString(datas); System.out.println("str = " + str); closeConn(connection); }
使用命令組合 sort
#-n:?--numeric-sort? ? 按照數(shù)字的值進(jìn)行比較
#-k:--key=POS1[,POS2]? ? ?start a key at POS1 (origin 1), end it at POS2
? ? ? ? 按指定的列做排序
#-r:--reverse? ? 反序排列
-t:指定排序用的字段的分隔符
sort -t ":" -k 3 -nr /etc/passwd
按兩個(gè)字段做排序:
sort -t: -k7 -k3nr /etc/passwd
參考:http://www.dbjr.com.cn/article/134816.htm
head
head?? -n? 1? 顯示文件前1行內(nèi)容
head?? -n? -1? 顯示文件除了最后1行的內(nèi)容
head?? -c?? 5? 顯示文件前n個(gè)字節(jié)
?head?? -c?? -5? 顯示文件除了最后5個(gè)字節(jié)的內(nèi)容
awk
輸出指定列
awk '{print $1,$4}' test
?
格式化輸出,指定輸出分隔符
awk '{printf "%-8s %-10s\n",$1,$4}' test
也可以用
awk '{print $1,$2}'?OFS=' '
?指定輸入分隔符
awk -F, '{print $1,$2}' test
參考:http://www.dbjr.com.cn/article/174434.htm
到此這篇關(guān)于java實(shí)現(xiàn)服務(wù)器巡查的文章就介紹到這了,更多相關(guān)java服務(wù)器巡查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中三種常見Bean的初始化參數(shù)機(jī)制你了解嗎
在Spring框架中,Bean的實(shí)例化與初始化是一個(gè)復(fù)雜的過程,本文我們主要來聊一聊它的常見的三種機(jī)制:InitializingBean接口、BeanDefinitionRegistryPostProcessor接口和EnvironmentAware接口,感興趣的小伙伴可以了解下2023-11-11SpringBoot Maven項(xiàng)目中Model間的最佳繼承設(shè)計(jì)詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot中一個(gè)優(yōu)秀Maven項(xiàng)目的各Model間最佳繼承設(shè)計(jì)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-01-01