关于程序员:ssh2jsShell一套组合拳下来一年要花2080分钟做的工作竟然节省到52分钟~

前言

进入了新的一年,团队被调配了新的工作内容——每周巡检。

巡检工作简略,但须要人工重复性地登陆近程服务器、输出反复的命令,而后将命令的后果记录下来。每做一次预计花40分钟,但要每周做,一年52周,一年下来就要花40*52=2080分钟,这仅仅是团队一个人一年要花的工夫。

不能这么玩呀,纯纯工具人,所以我始终在思考如何用程序帮我主动巡检掉。这篇文章的呈现,阐明我的想法方向是正确的,收益可观一年要花2080分钟,被我减到52 分钟

如果再扩大程序帮忙到团队,这个公式将从40*52*团队人数变成1*52*团队人数,工夫等于金钱

未主动巡检:

手动连贯登陆近程服务器,再输出相应的命令获取后果,而后人工根据后果判断是否异样,相当麻烦,而且我要执行的命令不止一条。

主动巡检:

运行macOS笔记本创立好的快捷指令,它会主动巡检服务器,并且巡检实现后间接关上巡检后果表格。当然没有macOS仍然能够,但就是没有快捷指令这步,须要本人执行程序。

残缺源码:blog/ssh

实现

实现难点

自动化巡检思路简略,思路如下:

本地程序连贯登陆近程服务器→本地shell命令近程执行→本地程序获取命令后果→后果数据整顿成表格

实现过程中次要有以下两个难点:

  • Node.js本地运行程序如何连贯登陆近程服务器
  • 登陆近程服务器帐号权限有余,在应用sudo命令时,如何主动输出明码

实现细节

解决Node.js本地运行程序如何连贯登陆近程服务器:

社区已有的计划ssh2,它是用纯JavaScript为Node.js编写的SSH2客户端和服务器模块。能够应用它连贯到近程服务器,并且ssh2提供了办法能够执行shell命令。

ssh2官网案例:

//...
const { Client } = require('ssh2');
const conn = new Client();
conn.on('ready', () => {
  console.log('Client :: ready');
  //执行uptime
  conn.exec('uptime', (err, stream) => {
    if (err) throw err;
    stream.on('close', (code, signal) => {
      console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
      conn.end();
    }).on('data', (data) => {
      //监听数据
      console.log('STDOUT: ' + data);
    }).stderr.on('data', (data) => {
      console.log('STDERR: ' + data);
    });
  });
})
//...

官网案例仅执行一条shell命令,当依照程序顺次执行一条以上的命令,官网的这个写法会十分麻烦。例如:首先执行docker ps -a -q获取所有docker容器id,而后再docker logs --tail 200 id

 //...
 // 获取docker所有容器ID
 conn.exec('docker ps -a -q', (err, stream) => {
    if (err) throw err;
    stream.on('close', (code, signal) => {
      /**
        docker ps -a -q命令执行实现
        再执行docker logs -f --tail 200 id
      */
      conn.exec(`docker logs  --tail 200 ${id}`,(err,stream)=>{
         if (err) throw err;
          stream.on('close', () => {
          //如果命令再简单点,还须要持续这样写下去
          
          }).on('data', (data) => {
            console.log( data);
          }).stderr.on('data', (data) => {
            console.log(data);
          });
      })
      
    }).on('data', (data) => {
      console.log('STDOUT: ' + data);
    }).stderr.on('data', (data) => {
      console.log('STDERR: ' + data);
    });
  });
 //...

要想写法整洁点,咱们须要再给 exec办法用Promise包一层。

execFn.js:

module.exports = (c = conn) => {
    return (command) => {
        return new Promise((resolve, reject) => {
            c.exec(command, (err, stream) => {
                if (err) {
                    reject(err)
                    return
                }
                let result = ''
                stream.on('close', () => {
                    resolve(String(result))
                }).on('data', (data) => {
                    //data数据是Buffer类型,须要转化成字符串
                    result += data
                })
            })
        })
    }
}

包一层后,再执行命令:

const execFn = require('./execFn.js')

module.exports = (config, conn) => {
    conn.on('ready',async ()=>{
      const exec = execFn(conn)
      const result = await exec('docker ps -a -q')
      //...
      exec(`docker logs --tail 200 ${id}`)
    })
    //...
}

这样代码会显得更整洁点,应用也更不便。

解决登陆近程服务器帐号权限有余,在应用sudo命令时,如何主动输出明码,可行计划有两种:

  • 简略粗犷,间接应用root帐号密码进行登陆,这样即可不必思考如何跳过明码输出的交互
  • 应用shell管道命令echo '明码' | sudo -S 命令

root帐号密码团队不能给到我,所以我采纳了后者来解决。

shell实现主动输出明码办法不只有应用管道命令echo '明码' | sudo -S 命令,还有其余的办法,但它在主动巡检的场景中是最合适的,它不须要额定要求服务器下载其余工具包,像expect指令它就须要装置expect包。巡检不只巡检一台服务器,如果每台都装置expect包,这工作量也烦人。

未主动输出明码:

主动输出明码:

至此,自动化巡检难点之处已解决,上面的工作就是以执行shell命令返回的后果判断服务器状态是否失常,如:团队巡检文档规定当执行 docker info |grep -A 5 "WARNING"时,如果有返回后果则为异样。

//...
const before = `echo "${config.password}" | sudo -S `
exec(before + 'docker info |grep -A 5 "WARNING"').then((content) => {
    if (content) {
        rol[2] = '异样'
    }
})
//...

该局部逻辑以团队巡检文档内容为准,不过多赘述,该局部代码在sshServer.js文件。

为了做到巡检多台服务器的目标,巡检相干的逻辑代码应用函数进行包裹并从sshServer.js文件中导出。

sshServer.js:

const execFn = require('./execFn.js')
//...
module.exports = (config, conn) => {
    return new Promise((resolve, reject) => {
        const exec = execFn(conn)
        conn.on('ready', async (err) => {
            if (err) reject(err)
            console.log('连贯胜利');
            //省略
            
        }).connect({
            ...config,
            readyTimeout: 5000
        });
    })

}

所有的服务器帐号密码均搁置在config.json文件中:

[
    {
        "host": "xx",
        "port": "xx",
        "username": "xx",
        "password": "xx"
    }
    //...
]

config.json文件波及到服务器信息须要窃密,config.json文件不会被提交至仓库。

目录构造如下:

最初,将巡检的后果数据整顿成表格,如何将数据导出表格已有对应的文章实现阐明【Node.js】写一个数据主动整顿成表格的脚本

思路是一样的。

index.js

const { Client } = require('ssh2');
const configs = require('./config.json')
const sshServer = require('./sshServer.js');
const fs = require('fs');
const path = require('path');
const nodeXlsx = require('node-xlsx')

const promises = []

//表格数据 二维数组
const tables = [
    ['服务器ip', 'docker是否失常运行', 'docker近程拜访', 'Docker日志是否有报错信息']
]

configs.forEach((config) => {
    const conn = new Client();
    promises.push(sshServer(config, conn))
})

Promise.all(promises).then((data) => {
    data.forEach((d) => {
        if (Array.isArray(d)) {
            tables.push(d)
        }
    })
    //生成xlsx表格
    const buffer = nodeXlsx.build([{ name: '巡检', data: tables }])
    const file = path.join(__dirname, '/server.xlsx')
    fs.writeFileSync(file, buffer, 'utf-8')
})

巡检后果对立暂存于tables数组中,以便导出。

实现快捷指令巡检

应用命令行巡检还是太累了。 最好是鼠标点下主动触发主动巡检。

咱们能够借助Mac快捷指令自定义再简化下。

快捷指令能够运行Shell。这样只须要编写一个名字叫做【巡检服务器】的快捷指令。

运行Shell后,以WPS关上server.xlsx文件。

快捷指令增加至访达。

这样就能够轻松实现主动巡检服务器性能了。

总结

文章灵感来源于工作,通过应用Node.js+Shell+ssh2做到主动连贯登陆近程服务器,运行相干Shell命令,查看服务器程序运行是否失常等状况。

对于程序员来说,懒,才是第一生产力!!!

如果我的文章对你有帮忙,你的👍就是对我的最大反对^_^。

本文由mdnice多平台公布

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理