【问题标题】:asyncio and paramiko for concurrent ssh connectivity用于并发 ssh 连接的 asyncio 和 paramiko
【发布时间】:2022-07-29 15:56:47
【问题描述】:

我正在尝试加快与几个网络设备的 Paramiko SSH 连接。我想为此目的使用 asyncio,但我不确定我的实现是否正确,因为我没有看到执行时间有任何好处,如果我们不使用它,脚本每次执行大约 6 秒。这个想法是,让第二台主机启动其 SSH 连接,而无需等待第一台主机的 SSH 连接建立。

这是我当前的代码,它可以运行但没有任何好处。如果可以,请在此处提出如​​何使其工作或改进的任何建议。

import paramiko
import time
import asyncio

async def sshTest(ipaddress,deviceUsername,devicePassword,sshPort): #finalDict
    try:
            print("Performing SSH Connection to the device")
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(ipaddress, username=deviceUsername, password=devicePassword, port=sshPort, look_for_keys=False, allow_agent=False)
            print("Channel established")         
    except Exception as e:
        print(e)       

async def main():
    print("Session 1 \n")
    await sshTest('192.168.255.11','admin','admin','22')
    print("Session 2 \n")
    await sshTest('192.168.254.11','admin','admin','22')

if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    end = time.time()
    print("The time of execution of above program is :", end-start)

【问题讨论】:

  • 仅添加 async 关键字不会使函数异步,请查看 AsyncSSH

标签: ssh python-asyncio paramiko


【解决方案1】:

如果您想异步执行此任务,请创建一个任务列表并将每个异步任务添加到该列表中。使用await asyncio.gather(*tasks),您的函数将通过 I/O 绑定异步执行任务。

import paramiko
import time
import asyncio

async def sshTest(ipaddress,deviceUsername,devicePassword,sshPort): #finalDict
    try:
            print("Performing SSH Connection to the device")
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(ipaddress, username=deviceUsername, password=devicePassword, port=sshPort, look_for_keys=False, allow_agent=False)
            print("Channel established")         
    except Exception as e:
        print(e)       


async def main():
    start = time.time()

    ip_list = ['192.168.254.11','192.168.255.11']
    tasks = []
    for ip in ip_list:
        tasks.append(asyncio.create_task(sshTest(ip,'admin','admin','22')))
    await asyncio.gather(*tasks)

    end = time.time()
    print("The time of execution of above program is :", end-start)


if __name__ == "__main__":
    asyncio.run(main())
   

【讨论】:

    【解决方案2】:

    你真的可以按照上面的建议异步使用 paramiko。我认为只有一个线程,如果 paramiko 阻塞,它不会将控制权转移到另一个任务。库也需要异步设计,不是吗?所以如果你想要异步 ssh-connections,你必须使用 asyncssh。

    【讨论】: