服务器提供商以及其他人员可能需要时常查看服务器配置,例如服务器的系统版本、内存大小、磁盘大小等等。人为地去执行不同的命令查看服务器配置,必须熟悉系统指令的人员才方便查看,费时又费力,效率比较低下。所以,如果有方法能让使用者输入账号、密码、地址,就能查询到服务器信息的工具,那么非专业人员也能迅速获取到所需的数据。一方面提高了效率,另一方面降低了对使用者的专业技术要求。
如图:
大多数服务器使用的都是linux系统,我们可以用各种语言编写脚本,查询服务器配置信息。在这里,我们使用java完成这个需求。在java编写的程序里面有一个封装好的工具包JSch,实现了SSH2,使用它我们能连接到一个sshd服务器,使用端口转发、文件传输、执行命令等,大致上满足了我们的需求。JSch包含了两种方式向linux服务器发送命令,一种是shell通道,另一种是exec通道。
Shell通道是用流的方式向目标服务器发现命令,通过io流的方式发送指令和接受消息,就如各种linux的shell工具,特点是同一个连接里面可以实时交互,命令之间可以相互通信,缺点是不会自行关闭流和通道。
exec通道可以一次性执行一个或者多个命令,特点是执行命令后的数据会一次性返回,当输入流中反馈的数据读取完毕以后,会自动关闭通道,如果开多个exec通道执行多个命令,这些命令不会相互干扰,例如一个通道执行了命名cd到了其他文件夹下,其他通道不会受影响。
这里我们选择使用exec通道。查看服务器配置信息可能需要执行多条指令,如果开多个exec通道执行的话,执行速度相对会很慢,所以在这里我们选择了使用一条exec通道多条指令的策略。这种方式的优点是速度相对较快,但是缺点是一是没有交互,例如我不能先查出来服务器使用哪种防火墙,再执行相应的指令获取防火墙策略,二是不好区分反馈的信息究竟是哪条语句执行的结果,因为反馈的全部消息都混在了一起。针对这种情况,我们的处理方式是,执行冗余的指令,把查询几种防火墙防护策略的指令都执行一遍,解析的时候再判断究竟是哪种防火墙,然后在每条指令之间执行echo命令打印特殊字符用于解析时候切割字符串,解决难以区分反馈的消息是哪条指令执行的结果的问题。
例如:
public static void main(String[] args) throws Exception {
//SSHelper是封装好的ssh工具类,简单展示不考虑异常
SSHHelper sshHelper = new SSHHelper(IP地址, 22, “root”, 密码);
SSHResInfo sshResInfo = sshHelper.sendCmd(“ip link/ndf -hl”);
System.out.println(sshResInfo.getOutRes());
sshHelper.close();
}
返回结果:
此时不好判断,ip link指令和df -hl指令执行的反馈消息分别是什么,但是如果在两条指令之间加一条打印指令,如echo ds8ds!sd%nv,我们就能够通过该字符串来切分,判断哪些消息是哪条指令执行的结果。
这样就能达到只使用一条exec通道执行指令,速度相对较快,各个指令反馈消息又能区分开的要求。
最后,我们通过这种方式,根据不同的需求拼接指令,将执行后的反馈消息,解析出关键信息,如内存大小、磁盘大小、防火墙策略等封装成类,配合前端就能达到图一显示的效果。