2016-08-24 35 views
1

我已成功創建了讀取和寫入RDS的Lambda函數(app1)。AWS Lambda函數中的獨立python子進程

我的Lambda函數是用python2.7編寫的,並以壓縮包的形式上傳。

我在與我的RDS和Lambda函數相同的VPC中的EC2實例上創建並測試了壓縮包。

接下來,我在Lambda函數中添加了功能,使用subprocess.popen爲獨立的子進程(app2)創建po,並讓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概念 是導致APP 2爲「失敗」?通過「失敗」,我的意思是不寫創建新文件並寫入,也不像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)+"'}"; 

從輸出 「logger.info( 'PID:' + STR(PID))」 中app1.py

是這樣的:「PID :<在0x7f51aba2a550 >「

APP2

subprocess.Popen對象10
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() 

回答

2

只要處理函數返回,AWS Lambda環境就會終止。處理函數完成後,您無法在AWS Lambda環境中的後臺運行子流程。您需要編寫Lambda函數以等待子流程完成。

+0

我認爲這可能是問題。我在調用app2之後但在返回處理程序之前爲app1添加了60秒的睡眠時間,並且app2仍未顯示任何進度。我決定讓app2成爲一個單獨的lambda函數,並嘗試以這種方式獨立啓動它。感謝您的回答,並且對於我聲明的預期目的而言是正確的。 – Lance