重新启动后无法建立连接

问题描述 投票:-1回答:1

人,

重新启动后,我尝试重新连接到服务器时遇到了一个问题。我看到了其他有关类似问题的文章,但是我尝试的所有内容都带有相同的错误。

目标

重新启动后自动重新连接到服务器

脚本

ssh_client = SSHClient()
ssh_client.set_missing_host_key_policy(AutoAddPolicy())
ssh_client.connect(hostname=host,port=port, username=user, password=psw)
s = ssh_client.get_transport().open_session()
agent.AgentRequestHandler(s)

         try:
            stdin, stdout, stderr = ssh_client.exec_command(command, get_pty= True)
            get_output(stdout)
            channel = stdout.channel
            stdin.close()
            channel.shutdown_write()
            stdout_chunks = []
            stdout_chunks.append(channel.recv(len(channel.in_buffer)))
            while not channel.closed or channel.recv_ready() or channel.recv_stderr_ready():
                got_chunk = False
                readq, _, _ = select.select([stdout.channel], [], [])
                for c in readq:
                    if c.recv_ready():
                        stdout_chunks.append(channel.recv(len(c.in_buffer)))
                        got_chunk = True
                    if c.recv_stderr_ready():
                        stderr.channel.recv_stderr(len(c.in_stderr_buffer))
                        got_chunk = True
                    if not got_chunk \
                            and channel.exit_status_ready() \
                            and not channel.recv_stderr_ready() \
                            and not channel.recv_ready():
                        channel.shutdown_read()
                        channel.close()
                        break
            stdout.close()
            stderr.close()

        except (ConnectionResetError, SSHException):
            print('Connection died')

错误被try catch块缓存:

Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died

我在远程服务器上运行的脚本以重新启动命令结尾:

/sbin/shutdown -r now
python paramiko reboot
1个回答
1
投票

我将其作为答案发布,因为时间太长,无法在评论中进行解释。

您的代码仍然缺少部分,因为我们不知道您如何称呼try / except结构以及捕获异常时会发生什么。但是,如果我从您的缩进量中得出的猜测是,如果捕获到异常,则将以某种方式重复try / except。

您似乎在逻辑上依赖于通道关闭状态,但是有一个TCP套接字形式的底层。重新启动服务器时,您的通道消失了,但是TCP层也消失了。在异常处理中,您将需要重新创建它。

我会尝试这样的事情:

try:
    ...
    ...
    ...
    stdout.close()
    stderr.close()
except (...):
    sleep(2)  # to prevent a busyloop when your server is rebooting      
    try:
        ssh_client.close()  # Close the connection just in case it is alive
    except:
        pass    # We do not care if it succeeds or fails
    counter = 0     # optional
    while True:
        sleep(2)    # to prevent a busyloop when your server is rebooting
        counter += 1
        if counter > X:
            print("server permanently down, exiting")
            exit (1)
        try:
            ssh_client.connect(hostname=host,port=port, username=user, password=psw)
            s = ssh_client.get_transport().open_session()
            break    # We have a liftoff
        except:
            pass     # Server not responding yet. Try again. 

((我没有测试上面的代码,只是在这里写出这个想法。这里可能有错别字)

您可以忽略计数器部分。如果服务器长期停机,我通常使用计数器来防止程序尝试直到母牛回家。如果您想继续尝试,请删除这些。如果使用它们,只需将X设置得足够高,以使服务器有足够的时间来重新引导,然后再进行一些重新引导。

关键部分是在发生错误后重新创建TCP连接,只有在您再次具有有效的连接时才离开错误处理程序。

我们尝试关闭现有连接,以防万一问题不在于连接丢失而避免耗尽服务器资源,但是我们不关心它是成功还是失败。然后,我们从头开始重新创建连接。

这可能会或可能不会在您的情况下起作用,因为我们从您的代码中不知道您在例外后如何重新输入此信息-并且您似乎也不确定基于您的评论。

© www.soinside.com 2019 - 2024. All rights reserved.