扭曲透视经纪人服务器端延迟

Kir*_*ers 6 python twisted

我正在使用twisted的Perspective Broker在客户端和服务器之间进行通信.客户端从服务器请求远程方法'remote_ssh'.这会导致PB服务器使用Paramiko的SSH库启动SSH连接,并从远程设备检索配置.

这一切都运行正常,但是当我为多个远程设备执行此操作时,我看到以下行为 - Perspective Broker客户端将所有请求发送到PB服务器.然后PB服务器将逐个执行这些请求(这很好),但是在它们全部完成之前它不会返回任何结果.

这是相关的PB服务器端代码:

class RMethods(pb.Root):

    def remote_ssh(self, aDict):

        self.login('SSH', aDict)        # Login to remote device
        response = self.aSSH.retrieve() # Retrieve the config
        self.aSSH.close()

        return response


if __name__ == "__main__":
    reactor.listenTCP(1885, pb.PBServerFactory(RMethods()))
    reactor.run()
Run Code Online (Sandbox Code Playgroud)

从查看各种系统级信息(TCPDump和netstat),我看到以下内容(假设5次调用远程方法):

从PB客户端呼叫remote_ssh到PB服务器,五个远程设备几乎同时发生

   self.login device 1
   self.aSSH.retrieve() device 1
   self.aSSH.close() device 1

   self.login device 2
   self.aSSH.retrieve() device 2
   self.aSSH.close() device 2

   ...

   self.login device 5
   self.aSSH.retrieve() device 5
   self.aSSH.close() device 5

   return results for all 5 devices  
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它等待返回结果(即为什么它等到device5完成后才返回device1的结果).

Jea*_*one 5

发生这种情况是因为在反应堆有机会运行之前无法发送响应.如果所有五个请求大约在同一时间到达,则反应堆可能会唤醒一次并同时注意到所有五个请求.它会将所有五个调度到PB服务器.该remote_ssh方法将为其中一个服务,阻止整个时间.完成后,响应将(几乎可以肯定)排队.然后该remote_ssh方法将为下一个方法提供服务,该响应将排队.依此类推,直到所有请求都已处理完毕.然后反应堆将完成调度原始的5个事件组并继续进行下一个事件.当它继续时,它将找到准备好发送的数据并开始发送它.

换句话说,阻塞阻止了反应堆的操作,包括阻止它发送准备发送的输出.

您可以尝试使用Twisted Conch作为SSH客户端,这可以让您无阻塞地执行SSH工作,或者您可以尝试将现有的SSH代码与线程一起使用(假设它可以成为线程安全的)或多个进程.