Tagged: Lambda

AWS Sam with Golang

AWS Lambda 를 작성하는 방법, 정확하게는 Serverless 의 API 를 작성하는 방법으로 SAM 을 사용한다. 그런데, SAM 을 이용해서 Runtime 을 Golang 으로 하려고 할 경우에 잘 안되는 경우가 발생한다. 2023년 말에 변화가 있었다.

이 문서는 위 문서의 내용을 요약한 것이다.

Error: There are no Template options available to be selected.

SAM 명령어를 이용해 Golang 런타임으로 생성할려고 하면 다음과 같이 오류가 발생한다.

SAM 명령어에 옵션으로 –runtime go1.x 를 지정하면 위와같은 오류가 발생한다. AWS 공식문서에 따르면 이제 go1.x 는 없어졌다. 대신에 provided.al2 를 사용해야 한다.

Template.yml 파일 변화

–runtime 옵션에 provided.al2 를 사용하면 template.yml 파일에도 변화가 생긴다.

Metadata 가 추가 된다. Runtime 이야 옵션으로 제공한 그대로 인데, Handler 가 bootstrap 이다. 이것을 바꿔서는 안된다. 또, Runtime 을 provided.al2 로 할 경우에 Lambda 의 Go 바이너리 실행 파일의 이름은 반드시 bootstrap 이여야 한다.

실행파일 이름은 반드시 bootstrap

Golang 의 람다 실행파일은 반드시 bootstrap 이어야 한다. 따라서 다음과 같이 컴파일해야 한다.

bootstrap 이 아닌 경우에는 실행되지 않는다.

-tags lambda.norpc 빌드 옵션 추가

bootstrap 바이너리를 빌드할때에는 반드시 -tags lambda.norpc 를 주어야 한다. AWS 공식 문서에 따르면 go1.x 에서는 필요했지만 provided.al2 로 런타임이 변경되면서 rpc 가 필요 없어졌다고 한다. 따라서 빌드할때에는 반드시 norpc 가 되도록 옵션을 지정해 줘야 한다.

변경사항이 많지는 않지만 위에 서술한 옵션들을 지키지 않을 경우에 문제가 된다. 실행파일 이름과 norpc 는 반드시 해줘야 하며 template.yml 에서도 필요한 내용이 있어야 한다. 그렇지 않으면 별것도 아닌 것으로 인해서 많은 시간을 허비하게 될 것이다.

sam build 시 SSL 접속 에러 해결 방

다음과 같이 sam build 시 SSL 접속 에러가 발생할 수 있다.

이럴때에는 실행하는 위치에 pip.conf 파일을 다음과 같은 내용으로 만든다.

그리고 이 파일에 대한 환경변수를 지정해 준다.

다시 sam build 를 수행하면 정상적으로 실행이 된다.

만일 컨테이너를 사용한다면 다음과 같이 하면 된다.

Collection Sort Lamba in Java

Java 8 이전에서 객체나 Map 같은 것을 정렬하기 위해서는 Collections 을 사용해야만 했다. 예를들어 다음과 같은 소스다.

하지만 Java 8 에 도임된 람다(Lambda) 를 사용할 경우에 이를 간단하게 해결할 수 있다.

더 나가 람다는 타입을 정의하지 않아도 된다. 컴파일러가 타입을 추론(Inferring) 하게 된다. 따라서 다음과 같이 간단하게 쓸 수 있다.

Java 8 람다 표현식

이 글은 다음의 Youtube 강의 내용을 요약 정리한 것입니다.

  • Java 8 Lambda Basics – Java Brains

왜 람다(Lambda) 인가?

  • 함수형 프로그램이 가능하다.
  • 읽기 쉽고 간결한 코드
  • API 나 라이브러리 사용이 좀 더 쉽다.
  • 패러럴 프로그래밍이 가능하다.

람다는 함수 자체를 값으롤 할당할 수 있는 Inline 함수처럼 표현된다.

 

람다 표현식(Lambda Expressions)

자바에서 메소드로 불리우는 함수 표현식은 대략 다음과 같은 형식을 갖는다.

Inline Values

위 예제는 Inline Values 가 무엇인지 보여준다. 별다른 객체, 메소드의 도움이 바로 할당하는 형식이 바로 Inline Values 라고 보면 된다.

그렇다면 코드 블럭(Code Block) 자체를 인라인으로 할당 할 수 있지 않을까? 다음과 같이 말이다.

실제로 JavaScript 에서는 Inline 함수라고 해서 존재한다. 다음과 같은 형식을 갖는다.

Java 8 에서의 람다 표현식은 JavaScript 에서의 인라인 표기와 유사하다.

HelloWorld 람다

HelloWorld 를 통해서 람다 표현식을 익혀보자.

전형적인 HelloWorld 코드다. 이것을 람다 표현식으로 어떻게 바꿀까? 먼저 메소드 자체를 Inline Value 할당하듯이 가상의 변수에 할당해보자. 다음과 같이.

public 은 접근제한자라고 해서 protected, private 등이 있다. 변수에 할당하는 행위에서 있어서 이러한 접근제한자는 의미가 없다. OOP 에서는 객체의 변수를 직접 받는것이 아니라 메소드를 통해서 할당 받는데, 람다 표현식에서는 Inline Value 로 직접 할당하는 방식이기 때문에 무의미하다. 지우자!

코드를 다시보면 perform  이라는 함수 이름이 존재한다. 하지만 코드 블럭자체를 왼쪽 변수에 할당하고 그러한 코드 블럭은 왼쪽 aBlockOfCode 를 호출함으로써 동작하게 될터이다. 따라서 perform 이라는 함수 자체를 지칭하는 이름은 불 필요하다. 이는 앞서본 JavaScript 의 인라인함수 표현식에서처럼 할당되는 함수의 이름이 없는것과 같다. 지우자!

void 는 리턴타입을 말한다. 아무런 리턴도 없다는 의미이기도 하다. Java 8 컴파일러는 똑똑하다. 람다 표현식에서 리턴타입을 명시하지 않더라도 컴파일러가 알아서 해준다. 지우자!

다 됐다. Java 8 에서 람다 표현식에서는 ->  를 이용한다. 다음이 Java 8의 람다 표현식의 완성이다.

이게 정상적인 코드라구? 그렇다. Java 8 에 도입된 람다표현식이다. 정확하게 잘 동작한다. 위를 좀 더 간결하게 바꿔 쓸수도 있다.

 

람다(Lambda) 예제.

다음을 람다 표현식으로 바꿔보자.

Inline 변수 할당이기 때문에 객체 접근제한자는 필요가 없다. public 삭제..

Inline 변수 할당이기 때문에 double 이라는 함수자체이 이름도 필요가 없다. double 삭제.. 그러면 다음과 같은 형태만 남는다.

자바 컴파일러는 매우 똑똑하다. 리턴타입을 추론해 맞춰준다. 먼저 인자 타입이 int 형이라 결과도 나름대로 int 형일것으로 추정하기도 하고 리턴 되는 계산을 하면서 리턴타입을 추론하기도한다. 별도로 리턴타입을 정의해줄 필요가 없다. int 리턴타입 삭제…

그렇게 하고 나면 다음과 같이 람다 표현식을 쓸수 있게 된다.

람다 표현식이다. 하지만 이를 좀 더 줄이면 다음과 같이 쓸 수 있다.

한줄로 다 작성할 수가 있다면 {} 블럭을 사용할 필요가 없고 {} 없는 경우에 return 을 쓰지 않아도 된다.

모든 람다가 {} 이 필요 없는 것은 아니다. 다음과 같이 블럭내에 로직이 들어갈 경우에 {} 블럭과 return 이 필요하다.

문자열 길이를 알아내고자 한다면 어떻게 람다 표현식을 쓸 수 있나? 다음과 같다.

물론, 앞에서 처럼 뭔가 로직을 넣어야 한다면 {} 감싸고 return 을 해주면 된다.