java实现服务器巡查的代码
⽬录
需求
批量ping
1.Jdk1.5的InetAddresss⽅式
2.最简单的办法,直接调⽤CMD
3.Java调⽤shell执⾏ping命令
批量ssh检查
需求:
依赖引⼊
⼯具封装
密码核对
资源巡查
使⽤命令组合 sort
head
awk
需求
⽤户,给了⼀⼤批服务器,需要检查服务器能否ping通,ssh密码是否正常,以及检查服务器的cpu,内存,硬盘占⽤情况。⼀个个检查肯定不现实,于是希望通过代码实现。
批量ping
1.Jdk1.5的InetAddresss⽅式
注意:使⽤时应注意,如果远程服务器设置了防⽕墙或相关的配制,可能会影响到结果。另外,由于发送ICMP请求需要程序对系统有⼀定的权限,当这个权限⽆法满⾜时, isReachable⽅法将试着连接远程
主机的TCP端⼝。可能出现isReachable=false但是⽤cmd验证却能够ping 通的情况。
代码实现:
/**
* 这个不可⾏,和ping的结果并不完全⼀致尽量别⽤
* @param ip
* @return
*/
public static boolean netOk(String ip){
InetAddress address=null;
boolean netOk=false;
try {
address =ByName(ip);
netOk= address.isReachable(5000);
} catch (Exception e) {
e.printStackTrace();
}
return  netOk;
}
2.最简单的办法,直接调⽤CMD
注意:如果出现Windows环境下可以正常ping通的,⽽在centOS(Linux)⾥⾯⽆法ping通,可能是被ping的设备上有设置ping包⼤⼩限制,限制在了32位以内。
最终使⽤
Process pro = Runtime().exec("ping -s 32 " + ipAddress );
并解析结果来进⾏判断。
命令⾏基础
其中n是次数,w是超时时间,单位是毫秒
ping -n 1 -w 1000 9.8.8.8
代码实现:
/**
*
* @param ipAddress
* @param pingTimes 单位是毫秒
* @param timeOut
* @return
*/
public  static  boolean ping(String ipAddress,  int pingTimes,  int timeOut) {
BufferedReader in =  null;
Runtime r = Runtime();  //  将要执⾏的ping命令,此命令是windows格式的命令
String pingCommand = "ping " + ipAddress + " -n " + pingTimes    + " -w " + timeOut;
try {    //  执⾏命令并获取输出
System.out.println(pingCommand);
Process p = r.exec(pingCommand);
if (p ==  null) {
return  false;
}
in =  new BufferedReader( new InputStream()));    //  逐⾏检查输出,计算类似出现=23ms TTL=62字样的次数            int connectedCount = 0;
String line =  null;
while ((line = in.readLine()) !=  null) {
connectedCount += getCheckResult(line);
}    //  如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真
return connectedCount == pingTimes;
}  catch (Exception ex) {
ex.printStackTrace();    //  出现异常则返回假
return  false;
}  finally {
try {
in.close();
}  catch (IOException e) {
e.printStackTrace();
}
}
}
// 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.
private  static  int getCheckResult(String line) {  //  System.out.println("控制台输出的结果为:"+line);
Pattern pattern = Patternpile("(\\d+ms)(\\s+)(TTL=\\d+)",    Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
return 1;
}
return 0;
}
3.Java调⽤shell执⾏ping命令
注意:这种需要在linux环境执⾏
命令⾏基础
其中 -c是次数,-W是超时时间,单位是秒
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){
ains("ttl")){
return true;
}
}
return false;
}
/**
* 执⾏shell并且返回结果
* @param sh
* @return
*/
public static String exeShell(String sh){
Process process = null;
List<String> processList = new ArrayList<String>();
try {
process = Runtime().exec(sh);
BufferedReader input = new BufferedReader(new InputStream()));
String line = "";
while ((line = adLine()) != null) {
processList.add(line);
}
input.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
String result = StringUtils.join(processList, "\n");
return result;
}
批量ssh检查
需求:
先检查⽹络是否通(这⾥我是先检查ssh⽤的22端⼝),不通的记录下来,端⼝通的,再⽤⽂档记录的登录信息ssh登录,将登录成功的和不成功的分别记录下来。
注意:有的服务器有安全策略,不要同⼀台服务器多次尝试。
依赖引⼊
<!-- ssh  -->
<dependency>
<groupId&hz.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.InetSocketAddress;
import java.Socket;
import java.util.Calendar;
import org.apachemons.lang3.StringUtils;
hz.ssh2.Connection;
hz.ssh2.Session;
hz.ssh2.StreamGobbler;
public class SshUtil {
private static String DEFAULT_CHAR_SET = "UTF-8";
private static String tipStr = "=======================%s=======================";
private static String splitStr = "=====================================================";
/**
* 登录主机
* @return
*      登录成功返回true,否则返回false
*/
public static Connection login(String ip, String userName, String password){
boolean isAuthenticated = false;
Connection conn = null;
long startTime = Instance().getTimeInMillis();
try {
conn = new Connection(ip);
isAuthenticated = conn.authenticateWithPassword(userName, password); // 认证
if(isAuthenticated){
System.out.println(String.format(tipStr, "认证成功"));
} else {
System.out.println(String.format(tipStr, "认证失败"));
}
} catch (IOException e) {
e.printStackTrace();
}
long endTime = Instance().getTimeInMillis();
System.out.println("登录⽤时: " + (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 = Instance().getTimeInMillis();
try {
conn = new Connection(ip);
isAuthenticated = conn.authenticateWithPassword(userName, password); // 认证
if(isAuthenticated){
System.out.println(String.format(tipStr, "认证成功"));
return true;
} else {
System.out.println(String.format(tipStr, "认证失败"));
return false;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null){
conn.close();
}
}
long endTime = Instance().getTimeInMillis();
System.out.println("登录⽤时: " + (endTime - startTime)/1000.0 + "s\n" + splitStr);
return false;
}
/**
* 远程执⾏shell脚本或者命令
* @param cmd
*      即将执⾏的命令
* @return
*      命令执⾏完后返回的结果值
*/
public static String execute(Connection conn, String cmd){
String result = "";
Session session = null;
try {
if(conn != null){
session = conn.openSession();  // 打开⼀个会话
result = Stdout(), DEFAULT_CHAR_SET);
//如果为得到标准输出为空,说明脚本执⾏出错了
if(StringUtils.isBlank(result)){
result = Stderr(), DEFAULT_CHAR_SET);
}else{
System.out.println("【执⾏命令成功】\n执⾏的命令如下:\n" + cmd);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
if (session != null) {
session.close();
}
}
return result;
}
/**
* 解析脚本执⾏返回的结果集
* @param in 输⼊流对象
* @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) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String();
}
/**
* 判断端⼝是否通
* @param host
* @param port
* @param timeout
* @return
*/
public static boolean isHostConnectable(String host, int port,int timeout) {
Socket socket = new Socket();
try {
socket.setSoTimeout(timeout);
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
}
密码核对
public static void main(String[] args){
String ip = "192.168.4.188";  // 此处根据实际情况,换成⾃⼰需要访问的主机IP
printf输出格式java
String userName = "root";
String password = "123456";
boolean flag = pwdCheck(ip, userName, password);
System.out.println("flag===="+flag);
}
资源巡查
使⽤封装的sshUtil
public static void main(String[] args){
// 此处根据实际情况,换成⾃⼰需要访问的主机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);
//查看最⼤的盘指定---为分隔符,默认的分隔符java⽆法指定
String max_disk_cmd="df | sort -k2nr | head -1 | awk '{print $2,$3,$4,$5}' OFS='---' ";
//查看内存使⽤情况
String free_mem_cmd="free | sort -k2nr | head -1 | awk '{print $2,$3,$4}' OFS='---'";
//计算cpu使⽤率, -n number:指定在结束前应该产⽣的最⼤迭代次数或帧数,⼀般迭代次数越⼤,获取到的cpu使⽤率越准确; 本脚本中是迭代了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 = String(datas);
System.out.println("str = " + str);
closeConn(connection);
}
使⽤命令组合 sort
#-n: --numeric-sort    按照数字的值进⾏⽐较
#-k:--key=POS1[,POS2]    start a key at POS1 (origin 1), end it at POS2