tornado 异步执行shell命令并返回执行结果

思路: 通过tornado 框架构建web 服务器,通过执行后台命令程序获取监控目标状态或监控结果,根据状态或结果,通过websocket 发送信息到前端进行相应的展现。

问题: tornado web框架是异步处理的,其核心是将事务都放入到ioloop异步循环中。但通常使用python调用shell脚本或者执行的shell命令,以及python打开文件的操作都是同步阻塞模式,无法加入到ioloop中。在下面的连接中提到了如何将shell命令通过异步方式执行并获取执行结果。

https://www.cnblogs.com/senjougahara/p/6091652.html

根据 tornado 官方文档,tornado.process.Subprocess(*args**kwargs)  对象是 subprocess.popen的装饰器,增加了对IOStream的支持。

stdin,stdout和stderr 可以是tornado.process.Subprocess.STREAM的值,将subproess的结果属性放入到pipeIOStream。如果使用这个选项,调用者将负责steam的关闭。

注意,subprocess.STREAM 和 set_exit_callback 以及wait_for_exit 方法不适用于windows平台,也就是在windows中只能用subprocess.Popen()

上述链接中我主要使用了这个方法:

import tornado.gen
from tornado.process import Subprocess

@tornado.gen.coroutine
def run_command(command):
    """run command"""
    process = Subprocess(
        [command],
        stdout=Subprocess.STREAM,
        stderr=Subprocess.STREAM,
        shell=True
    )
    out, err = yield [process.stdout.read_until_close(), process.stderr.read_until_close()]
    raise tornado.gen.Return((out, err))

然后定义一个异步函数,在期中调用上述函数执行命令,并接收返回的结果。

async def healthy_check():
    GW = "192.168.1.1"
    cmd_gw  = "ping -c 3 " + GW + " | grep " + GW  + " | wc -l"
    """run command"""
    while True:
        await asyncio.sleep(1)
        r_cmd_res,r_cmd_err = await run_command(cmd_gw)
        if r_cmd_res.decode() == '5':
            websocket_inst.write_message("GW_UP")
         else:
            websocket_inst.write_message("GW_UP")
在tornado 中:
if __name__ == "__main__":
    app = Application()
    app.listen(options.port)
    io = tornado.ioloop.IOLoop.current()
    io.add_callback(healthy_check)    
    io.start()

 

  将链接中的代码改成异步原生状态也可以:只不过将yield 改成await即可。

async def run_command(command):
    """run command"""
    process = Subprocess(
        [command],
        stdout=Subprocess.STREAM,
        stderr=Subprocess.STREAM,
        shell=True
    )
    out = await process.stdout.read_until_close()
    err = await process.stderr.read_until_close()
    return (out, err)

通过这种方式,将shell命令、websocket 和tornado 结合起来实现对监控目标的监控,并将监控结果实时展现到前段界面。

可以观察到系统调用shell 执行命令的情况,可以看到,系统每次是创建不同的进程来执行命令,在具有大量监控目标时可能会有较大的开销。好处是系统调用完就关闭进程,能够支持的并发数要高,实际使用时,需要在系统新建和关闭进程的开销和并发数之间进行折中考虑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值