首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

如何通过 java 实现在多台 Linux 服务器间自动执行各种命令或查询日志-1

如何通过 java 实现在多台 Linux 服务器间自动执行各种命令或查询日志-1

简介系统的爆炸性增长让应用的分布式变的越来越普遍。虽然现有的分布式系统的应用,给予应用本身很大的可扩展性。但是相对来说,维护性就可能到其影响,让维护人员的工作量加倍和工作效率降低。其中,最常见的麻烦之一便是错误处理问题的查找。当用户需要根据错误日志来诊断问题出现的时间和相对位置的时候,多个服务器之间的相互切换和命令的重复键入是没有办法被避免的,用户需要重复各种简单而且单调的工作模式,在不同的机器当中重复实现。
现有的使用环境对于软件开发测试人员来说,大型的应用意味着对远程主机依赖会达到更高的层次。从应用环境的部署到命令的远程执行,都需要依赖各种客户端工具。对于开发人员,当每次执行的命令很多时,一般是把其写入到一个脚本里面,通过客户端工具进行远程登录后执行。但是每次的执行都只是对一个特定的服务器,但是现有的分布式系统让工作能够均衡的负载到各个服务器上面,这也加大在相同工作内容上服务器上面进行部署的工作,而且当脚本部署到各个服务器上面时,当其中的一个脚本内容修改时,无法达到所有脚本的一致性,这也会导致很多的平衡性的问题。
图 1. 原始使用 SSH 工作流程开发人员更加喜欢可智能化的集成开发环境,比如说,sshxcute 是一个现存的基于 Java 的远程执行类库,开发人员可以通过运行一个 Java    类来部署环境,远程执行命令或者脚本。他是一个框架,允许工程师利用 Java 代码通过 ssh 远程执行 Linux/Unix 系统上的命令或者脚本,这种方式不管是针对软件测试还是系统部署,都简化了自动化测试与系统部署的步骤。
SSHXcute 的设置宗旨在于:
  • 最小的系统需求
  • 易用性
  • 内置命令/脚本任务执行功能
  • 易扩展
图 2. 使用 SSHxcute 工作流程图但是不论是客户端还是先有的 Java 执行类库,都有一个缺陷,那就是无法实现相同任务分布式服务器的自动切换。
缺陷分析测试人员在当下,如果发现问题后一般会执行如下步骤以获得错误日志,只有获得更准确的错误日志开发人员才能更快速的分析问题根本解决问题。
  • 测试人员发现界面或后台运行程序出现错误
  • 打开 Putty,连接 1 号应用 app 服务器,打开相关日志文档查找错误日志
  • 连接 1 号数据库服务器,打开相关日志文档查找错误日志
  • 连接 1 号后台任务管理服务器,打开相关日志文档查找错误日志
  • 下载各种配置文件,已查询错误
  • 重复步骤 1-5,遍历所有关联服务器(Job,App,DB)查找日志图 3. 测试人员手动检查服务器步骤图-1图 4. 测试人员手动检查服务器步骤图-2
实现方式SSHXcute 提供的 API 包含有关闭以及切换的操作,但是经过测试,现有的情况只是支持对单个服务器的连接。无论是调用关闭还是切换接口,都无法影响现有的连接。
只有对现有的源代码进行改进,才能够自动实现多服务器之间的切换并且更够根据配置文件来自动实现。
如何实现自动遍历所有服务器在开发测试人员的日常分析中,经常要通过遍历大量不同的服务器以找到真正需要的日志,因此实现自动遍历所有服务器,能够大大缩短连接转换服务器的时间,提高效率。
实现代码如下:
清单 1:实现自动遍历所有服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//读取服务器磁盘空间信息命令,读取使用率大于 90%的
String cmd = "df -h | grep -b -E \\(9[1-9]\\%\\)\\|\\(100\\%\\)";
JSch sshSingleton = new JSch();
//从配置文件中加载用户名和密码
        Properties userProp = new Properties();
userProp.load(new FileReader("user.properties"));
        String userName = userProp.getProperty("username");
        String password = userProp.getProperty("password");
//从配置文件中加载服务器信息
        Properties serversProp = new Properties();
serversProp.load(new FileReader("servers.properties"));

        for (Map.Entry<Object, Object> serverProp : serversProp.entrySet()) {
            String name = (String) serverProp.getKey();
            String server = (String) serverProp.getValue();

            System.out.println("Start working on: " + name);
            Session session = sshSingleton.getSession(userName, server);
            session.setPassword(password);
            Properties config = new Properties();
//设置 SSH 连接时不进行公钥确认
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
//打开命令执行管道
            ChannelExec channel = (ChannelExec) session.openChannel("exec");
BufferedReader in = new BufferedReader(new InputStreamReader(
                    channel.getInputStream()));
            channel.setCommand(cmd);
            channel.connect();
//读取命令输出信息
            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println(msg);
            }

            channel.disconnect();
            session.disconnect();
        }




user.properties 用来存放用户名和密码:
1
2
username=admin
password=xxxxxxxx




servers.propesties用来存放 servers 的 IP 信息,例如:
1
2
3
4
5
6
#alias name = host name/IP
server1=192.168.0.11
server2=192.168.0.12
server3=192.168.0.13
server4=192.168.0.14
server5=192.168.0.15

返回列表