System Compleat.

'Lambda and Go'에 해당되는 글 1건

  1. AWS Lambda & Go!

AWS Lambda & Go!

Techs


(younjin.jeong@gmail.com, 정윤진) 


최근 AWS에서 새로운 서비스가 나왔는데, 이름하야 Lambda. 

구구절절이 자세한 설명은 http://aws.amazon.com/ko/lambda/?nc2=h_ls 여기에서. 





읽은척 매뉴얼처럼 요약 버전으로 살짜쿵 정리해 보자면, "이벤트 기반으로 호출되는 function level 의 컴퓨팅 서비스. 즉, 서버를 켜는 대신 코드를 쓰자!" 로 요약이 가능. 그럼 어떤 코드를 쓸 수 있는데? 라고 묻는다면, 일단 제품이 발매 될 때 (지금은 preview 기간) 에 지원되는 언어는 Javascript 로, node.js 코드를 돌릴 수 있다. 지원 되는 버전은 다음의 링크에서. http://docs.aws.amazon.com/lambda/latest/dg/lambda-introduction.html#current-supported-versions 


그럼 node.js 만 돌릴 수 있나요 하면 그것은 아니고, 64비트 리눅스 환경에서 동작 할 수 있도록 static 하게 컴파일된 바이너리 또는 external library 를 사용하는 경우에도 함깨 packing 해서 업르도 해 주면 동작할 수 있다. 단, 이 경우에도 trigger 는 node.js 가 되어야 하기 때문에, 이렇게 올라간 바이너리는 child_process 와 같은 도구로 spawn 을 하면 된다. Process 및 thread 를 사용하는 것이 가능하달까. http://aws.amazon.com/lambda/faqs/ 



어쨌든 preview 권한을 획득하면 다음과 같은 화면에 접근이 가능하다. 







화면 왼쪽은 이벤트를 통해 Lambda 에 전달할 json 을 보여준다. 오른쪽의 경우에는 이 이벤트를 통해 트리거될 함수이며, 양쪽 모두 브라우저에서 직접 코드의 수정이 가능하다. 그 아래 보이는 화면은 함수를 invoke 한 경우 그 실행 결과로 출력되는 console output 을 보여주며, 이는 나중에 CloudWatch 를 통해 log stream 으로 확인이 가능하겠다. 



왼쪽의 event 로 함수에 전달된는 json 은 S3 / Kinesis / DynamoDB stream 의 템플릿을 확인 할 수 있고, 원한다면 custom template 을 만들어서 전달하는것도 가능하다. 따라서 만약 S3에 어떤 파일이 업로드 된 경우, putObject 가 완료되면 lambda 로 이벤트가 전달되고, 이때 전달되는 json 에는 bucket 의 이름, key 와 같은 정보들이 함께 전달되어 thumbnail 을 생성한다던가 DynamoDB 의 table 에 link 를 업데이트한다던가 하는 동작을 수행 할 수 있겠다. 



위에서 설명했듯이 이러한 동작을 node.js 로 할 수 있도록 했지만, 이를 반드시 node.js 로 할 필요는 없기 때문에 여기에 요새 유행하는 Go 를 사용해 보면 어떨까나. AWS에서 Golang 에 대한 SDK 를 정식 배포하고 있지는 않지만, 다음의 링크에서 남이 만들어 놓은 것을 거져 먹을수 참조해 볼 수 있곘다. https://github.com/mitchellh/goamz  일단 땡큐. 



여기까지 생각하고 보니 이런 생각을 과연 나만했을까 하는 의심이 들어서 검색질을 했더니 얼씨구나 역시나. 

http://blog.0x82.com/2014/11/24/aws-lambda-functions-in-go/ 



나의 경우 OSX 를 사용하기 때문에 Go 의 corss compile (Lambda 는 64bit Linux 환경이므로) 설정이 필요했다. 무턱대고 돌리면 아래와 같은 에러를 뱉어주실 것임. 


$ GOOS=linux GOARCH=amd64 go build HelloWorld.go 

go build runtime: linux/amd64 must be bootstrapped using make.bash



OSX 에서 별도의 옵션없이 Golang 을 설치했다면 다음의 위치에서 Cross compile 을 위한 준비가 가능 


sudo GOOS=linux GOARCH=amd64 ./make.bash --no-clean

Password:

# Building C bootstrap tool.

cmd/dist


# Building compilers and Go bootstrap tool for host, darwin/amd64.

lib9

libbio

liblink

...

..

.

어쩌고 저쩌고 블라블라 

...

testing/quick

text/scanner



---

Installed Go for linux/amd64 in /usr/local/go

Installed commands in /usr/local/go/bin


prompt $




이러면 이제 크로스 컴파일 준비완료. 

Go 를 사용해서 원하는 코드를 마음껏 써준다. 



package main

import  (
	"fmt"
	"os"
)

func main() {
    fmt.Printf("%v, a message from Go \n", os.Args[1])
}


Linux 64bit 용으로 빌드 

 GOOS=linux GOARCH=amd64 go build hello.go



node.js 코드 작성 




//main.js
var child_process = require('child_process');

exports.handler = function(event, context) {
  var proc = child_process.spawn('./hello', [ JSON.stringify(event) ], { stdio: 'inherit' });

  proc.on('close', function(code) {
    if(code !== 0) {
      return context.done(new Error("Process exited with non-zero status code"));
    }

    context.done(null, 'done!');
  });
} 

 

압축 및 업로드. 업로드는 브라우저에서 해야 됨. CLI 로 하면 handler / file name 을 제대로 인식하지 못하는 경우가 발생. 아직 preview 라 그런듯.  


$ zip test.zip main.js hello

$ aws lambda upload-function --function-name MyFirstGoFunc --function-zip test.zip --runtime nodejs --role arn:aws:iam::xxxxxxxxx:role/lambda_exec_role --handler handler --mode event --timeout 10 --memory-size 128 --region us-west-2 

{

    "FunctionName": "MyFirstGoFunc", 

    "CodeSize": 568189, 

    "ConfigurationId": "c1745483-xxxxxxxx", 

    "MemorySize": 128, 

    "FunctionARN": "arn:aws:lambda:us-west-2:xxxxxxxxxx:function:MyFirstGoFunc", 

    "Handler": "handler", 

    "Role": "arn:aws:iam::xxxxxxxxxxxx:role/lambda_exec_role", 

    "Mode": "event", 

    "Timeout": 10, 

    "LastModified": "2014-12-23T05:55:10.647+0000", 

    "Runtime": "nodejs", 

    "Description": ""

}



브라우저를 통한 업로드. 






로그를 확인하려면 "Execution results" 부분의 Click here 를 통해 CloudWatch log stream 으로 이동하면 된다. 

그럼 compile 된 Go 코드가 수행되면서 argv[1] 로 받은 event json 이 예쁘게 print 되어 있는 모습을 확인 할 수 있다. 





Lambda 는 Function 에 할당하는 메모리의 크기에 따라 코드를 수행하는 플랫폼의 성능이 달라진다고 볼 수 있겠다. 아래의 간단한 uname -a 정보를 통해 Linux 64bit, C코드던 뭐던 좌우당간에 native code 도 동작시킬 수 있다고 보면 될 듯. 


exports.handler = function(event, context) {

  var exec = require('child_process').exec,
        child;

  child = exec('uname -a', function(error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        if (stderr) console.log('stderr: ' + stderr);
        if (error) console.log('error: ' + error); 
  });
  context.done(null, 'done!');
}





매뉴얼에 따르면 현재 지원되는 event source 는 Kinesis / DynamoDB stream, 그리고 S3 다. Lambda preview 에서 다른 event source 를 사용하려면 AWS CLI 도구가 반드시 필요하겠다. 



아직은 preview 상태지만, 나중에 production 으로 풀리게 되면 아주 재미난 서비스가 되리라 믿어 의심치 않는다.  :-)  


아울러 모든 필요한 정보는, 

http://aws.amazon.com/ko/lambda/ 

http://aws.amazon.com/ko/lambda/details/

http://aws.amazon.com/ko/lambda/getting-started/

http://aws.amazon.com/ko/lambda/faqs/


슝슝 


레알 백년만의 기술포스팅. ㅠㅠ 

(younjin.jeong@gmail.com, 정윤진)