задержка на стороне сервера витой перспективы - PullRequest
6 голосов
/ 20 августа 2011

Я использую Twisted Perspective Broker для связи между клиентом и сервером.Клиент запрашивает у сервера удаленный метод 'remote_ssh'.Это заставляет сервер PB инициировать соединение SSH с использованием библиотеки SSH Paramiko и получать конфигурацию с удаленного устройства.

Это все работает нормально, но когда я выполняю это для нескольких удаленных устройств, я вижу следующее поведение - клиент 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 вызовов удаленного метода):

Вызов remote_ssh с клиента PB на сервер 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  

Я не понимаю, почему он ожидает возврата результатов (т.е. почему он ожидает, пока устройство 5 завершит работу, прежде чем будут возвращены результаты для устройства 1).

1 Ответ

5 голосов
/ 20 августа 2011

Это происходит потому, что ответы не могут быть отправлены до тех пор, пока реактор не сможет запустить. Если все пять запросов поступают примерно в одно и то же время, реактор может проснуться один раз и заметить все пять из них одновременно. Он отправит все пять из них на сервер PB. Метод remote_ssh будет обслуживать один из них, блокируя все время. Когда это будет сделано, ответ (почти наверняка) будет поставлен в очередь. Затем метод remote_ssh будет обслуживать следующий, и этот ответ будет поставлен в очередь. И так до тех пор, пока все запросы не будут обработаны. Затем реактор завершит отправку исходной группы из 5 событий и перейдет к следующему. Когда он движется дальше, он найдет данные, готовые к отправке, и начнет их отправлять.

Другими словами, блокировка препятствует работе реактора, в том числе предотвращает отправку вывода, готового к отправке.

Вместо этого вы можете использовать Twisted Conch в качестве клиента SSH, что может позволить вам выполнять работу SSH без блокировки, или вы можете попробовать использовать существующий код SSH с потоками (при условии, что он может быть поточно-ориентированным) или несколькими процессами.

...