2017-05-21 1 views
0

그래서 전 세계에서 내가 뭘 잘못하고 있는지 알아 내려고 벽에 머리를 두드리는 중입니다. NodeJS 6.10을 사용하여 람다 함수를 작성했습니다. 이 함수는 내 S3 버킷 중 하나에서 여러 이미지를 검색하여 처리합니다. 나는 JavaScript의 비동기 성질을 수용하거나 어쨌든 시도하고 이들이 동시에 발생하도록 허용 한 다음 모든 작업이 완료된 후에 대기하고 수행합니다. 나는 코드를 여기에서 최소한으로 줄여서 필자가 볼 수있는 문제를 작성하고 재현 할 수있다. 문제는 이미지 중 어느 것도 검색되지 않는다는 것입니다. 사실, 람다 함수가 실제로 그것들을 검색하려고한다는 표시가없고 콜백이 항상 실행된다는 표시는 없습니다. 여기 S3JgetObject를 사용하는 Lambda의 NodeJS

코드입니다 :

console.log('Executing testImg method.'); 
var aws = require('aws-sdk'); 
var s3 = new aws.S3(); 

var imgData = {}; 

exports.handler = function(event, context, callback) { 

    var imgs = ['img_1', 'img_2', 'img_3', 'img_4', 'img_5', 'img_6', 'img_7', 'img_8']; 
    var imgPromises = []; 
    console.log('Grabbing images: ' + imgs); 
    imgs.forEach(function(img) { 
     console.log(img); 
     var myPromise = s3.getObject({ 
      Bucket: 'photoBucket', 
      Key: 'images/' + img + '.png' 
     }).promise(); 
     imgPromises.push(myPromise); 
     myPromise.then(function(result) { 
      console.log('Got ' + img); 
      imgData[img] = result.Body; 
     }); 
    }); 
    Promise.all(imgPromises).then(function() { 
     console.log(imgData); 
     context.succeed(); 
    }); 

} 

그리고 여기 람다의 출력입니다 : 당신이 출력에서 ​​볼 수 있듯이

START RequestId: <UUID> Version: $LATEST 
2017-05-21T18:53:31.187Z <UUID> Grabbing images: img_1,img_2,img_3,img_4,img_5,img_6,img_7,img_8 
2017-05-21T18:53:31.187Z <UUID> img_1 
2017-05-21T18:53:31.625Z <UUID> img_2 
2017-05-21T18:53:31.648Z <UUID> img_3 
2017-05-21T18:53:31.706Z <UUID> img_4 
2017-05-21T18:53:31.707Z <UUID> img_5 
2017-05-21T18:53:31.708Z <UUID> img_6 
2017-05-21T18:53:31.766Z <UUID> img_7 
2017-05-21T18:53:31.767Z <UUID> img_8 
END RequestId: <UUID> 
REPORT RequestId: <UUID> Duration: 10002.24 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 80 MB 
2017-05-21T18:53:41.173Z <UUID> Task timed out after 10.00 seconds 

에서,을 console.log (IMG) 라인이 어디에서 실행됩니다 이미지의 이름을 출력합니다. 그러나 개별 .then() 블록 안의 코드는 실행되지 않으며 (예 : console.log ('Got'+ img)) 최종 Promise.all 블록의 코드는 실행되지 않습니다 (전체 배열을 인쇄합니다 그리고이 기능을 종료하는 기능을 성공적으로 호출 또한

, 내가 시도 몇 가지 다른 것들 :..

  • 는 NodeJS + 람다 로컬을 사용하여 로컬 코드를 실행 그것은 잘 작동
  • 를 실행합니다. 비슷한 코드가 lambda-local없이 NodeJS에 있습니다. 괜찮습니다.
  • Lambda 역할을 사용할 수 있도록 명시 적 자격 증명을 사용하여 Lambda에서 코드를 실행합니다. AWS Lambda에서도 여전히 실패합니다.
  • 람다에서 하나의 이미지를 완벽하게 다운로드하는 것은 getObject를 여러 번 호출하는 것과 관련이 있습니다. 문서에서 이것이 나쁜 것임을 알 수는 없지만 좋아하는 것 같지 않습니다.
  • 루프 내에서 개별 myPromise.then() 호출을 제거하고 Promises.all() 블록의 모든 작업을 수행하고 실제로 AWS에서 실행중인 코드가 생성되지 않습니다. 그들은 각 동 기적이 일어날 수 있도록

나는 모두 함께 체인 수 있지만, 1) 파일의 수는 내가 미리 얻을 필요 해요 모르고 (동적 방식으로이 작업을 수행하기 어렵다) , 2) Async JS가 요즘과 관련된 모든 것에 반대하는 것으로 보인다.

힌트를 주시면 감사하겠습니다.

+1

코드가 성공적인 시나리오 만 처리하고 있습니다. 오류 메시지를 잡아서 출력하는 각각의 약속에'.catch()'또는'.then()'에 두 번째 함수를 추가해야합니다. 오류 메시지는 여러분에게 매우 좋은 단서를 줄 것입니다. 정확히 무슨 일이 일어나고 있는지. 또한 NAT 게이트웨이가없는 VPC 안에 람다 함수를 두어 (잠재적으로 S3 API 호출이 시간 초과되도록 할 것입니까?)? –

+0

고맙습니다. 이 문제를 해결 방법으로 게시했으면 좋겠어요. 한 지점에서 일부 catch/error 코드가 있었지만 연결할 기본 시간 제한은 대부분의 Lambda 함수 제한보다 길기 때문에 오류 검사 코드에 도달하지 못했습니다. 개인 데이터베이스 서버에 액세스하기 위해 VPC에 람다 (Lambda) 기능을 넣었으며 S3 종단점에 대해 생각조차하지 않았습니다. 올바르게 배치 된 NAT 게이트웨이와 일부 감소 된 HTTP 연결 시간 초과가이를 해결했습니다. 감사! –

답변

0

좋아,, S3는 공용 인터넷 리소스에 액세스 할 필요에 대한 마크 B의 의견은 자리에 있었고, 여기에 세 가지 가능한 해결 방법은 다음과 같습니다 다음에 대한 경로가있는 공공 서브넷

  • 이동 람다 함수 IGW를 통한 인터넷. 인스턴스를 공개 할 이유가 없기 때문에이 경로를 실제로 가고 싶지는 않지만 옵션입니다.
  • NAT 게이트웨이 (이전의 NAT 인스턴스)를 구성하고 해당 방법을 통해 인터넷 끝점에 트래픽을 허용하도록 경로 테이블을 구성합니다. 불행히도 NAT 게이트웨이는 비용이 들며 매월 청구서를 내고 싶지 않습니다.
  • 개인 서브넷 내의 내 VPC에 S3 끝점을 추가 한 다음 개인 서브넷의 항목이 해당 S3 끝점에 액세스 할 수 있도록 경로 테이블, 보안 그룹 및 정책을 구성했습니다. 이것은 완벽하게 작동합니다.

감사합니다. 다시 말하지만, 올바른 방향으로 조금 움직였습니다.

관련 문제