独立于AWS Lambda函数的Python子进程

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

我已成功创建一个读取和写入 RDS 的 Lambda 函数 (app1)。

我的Lambda函数是用python2.7编写的,并作为压缩包上传。

我在与 RDS 和 Lambda 函数相同的 VPC 中的 EC2 实例上创建并测试了压缩包。

接下来,我向 Lambda 函数添加了使用 subprocess.popen 弹出独立子进程 (app2) 的功能,并让 app1 返回,而 app2 子进程继续自行运行。我测试了 app1 将成功返回其处理程序的输出,而 app2 通过在 app2 中放置 60 秒睡眠并跟踪 app2 的输出文件来继续。

我在 EC2 实例中成功测试了 app1 和 app2 功能。

上传新包后,我的 app1 的行为似乎与预期完全一致,并立即返回其处理程序的输出,但 app2 功能并未“出现”实例化,但没有日志、错误或输出可供捕获应用程序2.

在app1中,我通过在独立的subprocess.popen之前和之后执行subprocess.check_output(['ls','-la'])来测试子进程的工作情况,并且本地文件夹与我的文件一起显示。除非没有按预期创建 app2output 文件。

两个问题

  1. AWS-Lambda 概念中是否有我遗漏的特殊内容导致 app2“失败”?我所说的“失败”是指不创建新文件并写入文件,也不像 app1 成功那样在 Cloudwatch 中创建任何日志,也不像 app1 那样打印到 Lambda 控制台。
  2. 如何在 AWS-Lambda 环境中捕获 app2 的任何输出(日志信息和错误)?

app1.py

import subprocess
import sys
import logging
import rds_config
import pymysql
#rds settings
rds_host  = "rdshost"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name
port = 3306

logger = logging.getLogger()
logger.setLevel(logging.INFO)

server_address = (rds_host, port)
try:
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
    sys.exit()

def handler(event, context):
    
    cur = conn.cursor()
    isql = "INSERT ..."
    cur.execute(isql)
    conn.commit()
    newid = cur.lastrowid
    cur.close()

    args = [str(newid),str(event['name'])]

    logger.info('ARGS: '+str(args))
    print 'pwd: '
    output = subprocess.check_output(['pwd'])
    print output
    print 'ls -la'
    output = subprocess.check_output(['ls','-l'])
    print output

    pid = subprocess.Popen([sys.executable, "app2.py"]+args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

    logger.info('PID: '+str(pid))
    output = subprocess.check_output(['ls','-l'])
    print output

    return "{'status':'success','newid':'"+str(newid)+"'}";

app1.py 中“logger.info('PID: '+str(pid))”的输出

就像:“PID:

app2

import sys
import logging
from datetime import datetime
import time

fo = open('app2output','a+')
fo.write("starting with: "+str(sys.argv)+"\n")

logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info("Starting with: "+str(sys.argv)+"\n")

#log accumulated processing time
t1 = datetime.now();
sleep(60)
t2 = datetime.now();
tstring = "{'t1':'"+str(t1)+"','t2':'"+str(t2)+"','args':'"+str(sys.argv[1])+"'}"
logger.info(tstring+"\n")
fo.write(tstring+"\n")
fo.close()
sys.exit()
python-2.7 amazon-web-services lambda subprocess popen
1个回答
6
投票

处理函数返回后,AWS Lambda 环境将立即终止。处理程序函数完成后,您无法在 AWS Lambda 环境中在后台运行子流程。您需要编写 Lambda 函数代码以等待子流程完成。

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