2016-08-24 8 views
1

RDSを読み書きするラムダ関数(app1)が正常に作成されました。AWSラムダ関数の独立したpythonサブプロセス

私のラムダ関数はpython2.7で書かれ、zip形式のパッケージとしてアップロードされます。

私は、RDSとLambda機能と同じVPCのEC2インスタンスでZIPパッケージを作成し、テストしました。

次に、私のラムダ関数に、subprocess.popenを使用して独立したサブプロセス(app2)をポップし、app2サブプロセスが単独で継続している間にapp1が戻るようにする機能を追加しました。私はapp2が60秒間sleepをapp2に入れ、app2の出力ファイルをテールすることによってapp1がハンドラの出力を正常に返すことをテストしました。

EC2インスタンスでapp1とapp2の機能を正常にテストしました。

新しいパッケージをアップロードした後、私のapp1は期待どおりに動作し、ハンドラの出力をすぐに返しますが、app2の機能はインスタンス化するためには表示されませんが、ログ、エラー、 app2からキャプチャします。

app1では、独立したsubproccess.popenの前後にsubprocess.check_output(['ls'、 ' - la'])を実行することでサブプロセスが動作し、ローカルフォルダがmyファイルで表示されることをテストしました。ただし、期待どおりに作成されたapp2outputファイルはありません。

二つの質問

  1. APP2は「失敗」をさせているAWS-ラムダ概念 で私が行方不明だと特別な何かがありますか? 「失敗」とは、新しいファイルを作成して書き込みをしたり、Cloudwatchでapp1と同じようにログを作成したり、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ラムダ環境は、ハンドラ関数が戻るとすぐに終了します。ハンドラ関数の完了後、AWS Lambda環境のバックグラウンドでサブプロセスを実行することはできません。サブプロセスが完了するのを待つためにラムダ関数をコーディングする必要があります。

+0

私はそれが問題かもしれないと思った。私はapp2を呼び出した後、ハンドラを返す前にapp1に60秒のスリープを追加しましたが、app2はまだ進捗状況を示していませんでした。私はapp2を別のラムダ関数にして、それを独立して試してみることにしました。答えをありがとう、それは私の述べられた意図された目的に関して正しいです。 – Lance