Python多处理子项挂起 - BOTO3 PARAMIKO

时间:2018-05-04 16:53:17

标签: python python-3.x multiprocessing boto3 paramiko

提前感谢您的帮助....我被困住了!我正在尝试编写一个脚本,该脚本将激活许多进程,每个进程执行以下操作:

    1.启动AWS EC2实例
    2.在该实例上执行脚本(脚本位于AMI上)
    3.脚本完成时终止实例

确实需要使用单独的VM,这对于本地其他类型的并行性来说并不是一个好例子。

以下脚本有效,但池工作人员停止响应。我通过target_cos列表获得部分内容,池工作人员什么都不做。他们所居住的流程仍然在运行,而且虚拟机仍在AWS上运行,但没有任何反应,而且事情似乎已经停止。

此外,当我使用带有单个池工作器的调试器/ IDE逐步执行它时,它可以正常工作。当我在mp池中运行许多工作程序时,它们会在~2次迭代后挂起。

import postgresql
import boto3
import paramiko
import time
import os
from multiprocessing import Pool


def spin_up(target_co):
    #What would happen with paramiko import here?

    ec2 = boto3.resource('ec2', region_name="us-west-2")
    instances = ec2.create_instances(ImageId='AMI-HERE',
                                 MinCount=1,
                                 MaxCount=1,
                                 KeyName="SECRET_KEY",
                                 InstanceType="t2.micro",
                                 Placement={
                                     'AvailabilityZone': 'us-west-2c'
                                 },
                                 SecurityGroups=[
                                     'Internal'
                                 ]
                                 )
    i = instances[0]

    print('WAITING FOR INSTANCE AVAILABILITY....')
    i.wait_until_running()
    print('OK.')

    i.load()

    k = paramiko.RSAKey.from_private_key_file('KEY_FILE_PATH.pem')
    c = paramiko.SSHClient()
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    success_flag = False
    attempt_counter = 0
    while success_flag == False and attempt_counter < 20:
        try:
            c.connect(hostname=i.public_dns_name, username="ubuntu", pkey=k)
            success_flag = True
        except:
            print('SSH Error.....Retrying.')
            attempt_counter += 1
            time.sleep(5)

    cmd = "python3 PATH_TO_EXECUTABLE_ON_AMI.py --target {} > LOG_FILE_ON_VM".format(target_co)

    transport = c.get_transport()
    channel = transport.open_session()
    channel.exec_command(cmd)

    while(channel.exit_status < 0):
        print(str(os.getpid()) + '  sleeping...')
        time.sleep(60)

    print('Terminating Instance....')
    i.terminate()
    print('Exiting....')


if __name__ == '__main__':

     target_cos = ['539',
              '542',
              '528',
              '48',
              '536',
              '26',
              '7',
              '20572',
              '10',
              '20',
              '101',
              '10023']

    # PARALLEL
    with Pool(processes=2) as pool:
        pool.map_async(spin_up, iter(target_cos))

        #are these actually required?
        pool.close()
        pool.join()

1 个答案:

答案 0 :(得分:0)

您不需要打开频道或睡觉。只做client.exec_command()。它会阻塞直到它完成。

我像这样运行你的代码:

import paramiko
import time
from multiprocessing import Pool


def spin_up(target_co):
    c = paramiko.SSHClient()
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    success_flag = False
    attempt_counter = 0
    while success_flag == False and attempt_counter < 20:
        try:
            c.connect(hostname='localhost', username="user", password='pass')
            success_flag = True
        except:
            print('SSH Error.....Retrying.')
            attempt_counter += 1
            time.sleep(5)

    cmd = "hostname"

    stdin, stdout, stderr = c.exec_command(cmd)

    print(stdout.read())
    print(stderr.read())
    print(stdout.channel.recv_exit_status())

if __name__ == '__main__':
    target_cos = ['539',
                  '542',
                  '528',
                  '48',
                  '536',
                  '26',
                  '7',
                  '20572',
                  '10',
                  '20',
                  '101',
                  '10023']

with Pool(processes=2) as pool:
    pool.map(spin_up, iter(target_cos))

我没有亚马逊的东西所以我无法测试。您可以使用map而不是map_async,因为在启动进程后您不需要执行任何操作。你可以阻止直到它完成。

如果仍有问题,请尝试将池更改为TreadPool。分叉和踩踏同时​​会引起问题。如果您之后仍有问题,可能需要查看AsyncSSH。它可以让你使用Asyncio来实现这一点,Asyncio是Python的酷炫新Async库。

忘记提及:你正在分叉和线程,因为多处理使用分叉而Paramiko使用线程。