zoukankan      html  css  js  c++  java
  • tornado 异步调用系统命令和非阻塞线程池

    项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测

    Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题.

    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))
    
    
    class NmapHandler(tornado.web.RequestHandler):
        """handle nmap check request"""
        @tornado.gen.coroutine
        def get(self):
            ip = self.get_argument("ip", None)
            if not ip:
                self.write(json.dumps({}))
                raise tornado.gen.Return(None)
    
            nmap_resp, _ = yield run_command(nmap % ip)
    
            self.write(json.dumps(
                {
                    "ip": ip,
                    "nmap_resp": nmap_resp
                }
            ))

    前一阵想到一个问题, run_command 如何进行异常处理. 原则上, 异常除了本地存储, 还应该上报调用者. 

    子进程执行的命令是固定的, 出现异常只会有两种情况, 第一, 创建子进程失败, 触发 OSError, 第二, 子进程中执行的 shell 命令失败, 报错信息重定向到stderr.

    所以, 暂时的处理是捕捉 OSError.

    使用非阻塞线程池, 调用 paramiko 来分发检测任务.

    from concurrent.futures import ThreadPoolExecutor
    from tornado.concurrent import run_on_executor
    
    
    class FailureHandler(tornado.web.RequestHandler):
        """handle server check request"""
        executor = ThreadPoolExecutor(100)
    
        @run_on_executor
        def get(self):
            ip = self.get_argument("ip", None)
            if not ip:
                self.write(json.dumps({}))
                raise tornado.gen.Return(None)
    
            resp = distributer(ip)
            if resp:
                resp = 0
            else:
                resp = 1
    
            self.write(json.dumps(
                {
                    "ip": ip,
                    "failure_rslt": resp
                }
            ))
  • 相关阅读:
    暑期学习录
    08管道命名符
    07输入输出重定向
    06grep与find命令详解
    05tar命令详解
    04文件目录管理命令
    03工作目录切换命令与文本文件编辑命令
    02系统状态检测命令
    01常用系统工作命令
    vue2.0细节剖析
  • 原文地址:https://www.cnblogs.com/senjougahara/p/6091652.html
Copyright © 2011-2022 走看看