提前感谢您的帮助....我被困住了!我正在尝试编写一个脚本,该脚本将激活许多进程,每个进程执行以下操作:
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()
答案 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使用线程。