扭曲的视角经纪人服务器端延迟
我正在使用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()
通过查看各种系统级信息(TCPDump 和 netstat),我看到以下内容(假设远程方法的 5 次调用):
发生从 PB 客户端到 PB 服务器的五个远程设备的调用 remote_ssh大约在同一时间,
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
我不明白为什么它要等待返回结果(即为什么它要等到 device5 完成后再返回 device1 的结果)。
I am using twisted's Perspective Broker to talk between the client and the server. The client requests from the server a remote method 'remote_ssh'. This causes the PB server to initiate an SSH connection using Paramiko's SSH library and retrieve a configuration from a remote device.
This all works fine, but when I have this execute for several remote devices I see the following behavior--the Perspective Broker client will send all of the requests to the PB server. The PB server will then execute these requests one-by-one (which is fine), but it won't return ANY of the results until they ALL complete.
Here is the relevant PB server side code:
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()
From looking at various system level information (TCPDump and netstat), I see the following (assume 5 calls of the remote method):
Call remote_ssh from PB Client to PB Server for the five remote devices happens at about the same time
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
I am not understanding why it waits to return the results (i.e. why does it wait until device5 completes before the results for device1 are returned).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
发生这种情况是因为反应器有机会运行之前无法发送响应。如果所有五个请求几乎同时到达,则反应堆可能会唤醒一次并同时注意到所有五个请求。它将把所有五个都分派到 PB 服务器。
remote_ssh
方法将为其中之一提供服务,并始终阻塞。完成后,响应将(几乎肯定)被排队。然后,remote_ssh
方法将为下一个方法提供服务,并且该响应将排队。依此类推,直到所有请求都得到处理。然后反应堆将完成最初的 5 个事件组的调度,并继续进行下一件事。当它继续前进时,它会发现数据准备好发送并开始发送。换句话说,阻塞会阻止反应器运行,包括阻止其发送准备发送的输出。
您可以尝试使用 Twisted Conch 作为 SSH 客户端,这可以让您在不阻塞的情况下完成 SSH 工作,或者您可以尝试使用现有的带有线程(假设可以使其成为线程安全)或多进程的 SSH 代码。
This happens because the responses can't be sent until the reactor has a chance to run. If all five requests arrive at about the same time, then the reactor may wake up once and notice all five of them at the same time. It will dispatch all five of them to the PB server. The
remote_ssh
method will service one of them, blocking the whole time. When it is done, the response will (almost certainly) be queued. Then theremote_ssh
method will service the next one, and that response will be queued. And so on until all of the requests have been handled. Then the reactor will have completed dispatching the original group of 5 events and move on to the next thing. When it moves on, it will find data ready to be sent and start to send it.In other words, blocking prevents the reactor from operating, including preventing it from sending output that is ready to be sent.
You could try Twisted Conch as your SSH client instead, which may let you do the SSH work without blocking, or you could try using your existing SSH code with threads (assuming it can be made thread-safe) or multiple processes.