【问题标题】:Independent python subprocess from AWS Lambda function来自 AWS Lambda 函数的独立 python 子进程
【发布时间】:2016-12-31 00:52:48
【问题描述】:

我已经成功创建了一个读写 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 的功能并未“出现”实例化,但没有日志、错误或要捕获的输出来自 app2。

在 app1 中,我通过在独立的 subproccess.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】:

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

    【讨论】:

    • 我认为这可能是问题所在。我在调用 app2 之后但在返回处理程序之前向 app1 添加了 60 秒的睡眠,并且 app2 仍然没有显示任何进度。我决定让 app2 成为一个单独的 lambda 函数,并尝试以这种方式独立启动它。感谢您的回答,关于我所说的预期目的是正确的。
    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2016-08-13
    • 2016-02-29
    • 1970-01-01
    相关资源
    最近更新 更多