💻 프로그래밍/node

[AWS Lambda] Nodejs 16.x 지원종료, 18.x 버전업 대응 요약(feat.s3)

피트웨어 제이 (FitwareJay) 2023. 10. 4. 22:16

안녕하세요! 제이입니다! 오늘은 사내에서 사용 중인 AWS Lambda의 Nodejs runtime 버전을 변경하면서 그 과정에 대한 요약과 어떤 점을 수정했는지 일부 요약 해보려고 합니다!

 

1. 버전관리


기본적으로 우리가 사용하고 있는 언어, 라이브러리, 프레임워크에 대한 지원종료에 대해서 인지하고 있어야 합니다. 저는 백엔드 센터 소속으로서 최근 백엔드에서 사용 중인 기술들에 대한 버전관리 및 업데이트를 진행(중)했습니다.

 

첫 번째로 저희가 사용 중인 AWS Lambda의 node버전을 체크했습니다. 버전 지원 종료에 대한 내용은 https://endoflife.date/nodejs 에서 쉽게 확인할 수 있습니다. 

(참고: https://endoflife.date/ 에는 다양한 언어, 제품에 대한 수명주기를 명시하고 있기 때문에 즐겨찾기 해놓으시면 많은 도움이 되실 거예요!)

 

nodejs 지원에 대한 내용

저희는 16.x를 사용 중이었는데 표를 보시다시피 23년도 9월 11일에 보안 지원까지 종료가 되었습니다. 좀 더 일찍 대응을 했으면 좋았을 텐데 그래도 당장 뭐 이슈가 있는 건 아니니 ㅎㅎ (늦었다 생각했을 때가 늦었다)

 

여하튼 현재 올릴 수 있는 안정된 버전은 18(LTS) 버전입니다. 25년 4월 30일까지 지원기간도 넉넉합니다!

 

https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

혹시 모르니 Lambda에서 nodejs18.x를 지원하는지도 체크해 줍니다! 확인해 보니 아주 다행히도 지원을 해주고 있었습니다. 다만 변경된 점은 nodejs18.x부터 AWS SDK V3를 사용합니다. (역시 쉬운 게 없습니다)

 

저희는 AWS SDK의 S3 관련 모듈을 사용하고 있었기 때문에 이 부분에 대한 변경점이 있을 거라 예상하며 적용을 진행했습니다.

 

 

2. 적용


저희는 serverless framework라는 툴을 사용하여 lambda 배포를 진행하고 있습니다. 로컬에서는 serverless offline이라는 라이브러리를 통해서 테스트를 하고 있고요! (진짜 좋습니다!)

 

기존에 사용하던 AWS SDK V2(aws-sdk)에서 V3로 변경되면서 패키지 구조와 사용되는 모듈들의 변화가 조금씩 있는 것 같습니다. aws 공식문서에서 V3(js) code 예제들을 제공하고 있습니다. (참고: AWSJavascriptSDK V3)

 

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/

yarn add @aws-sdk/client-s3

 

SDK v3부터는 각 모듈별로 따로 설치를 하는 것 같습니다. 공식문서에 되게 친절하게 나와있어서 이해하시기 어려운 부분은 없을 거예요! 이런 방식으로 변경된 이유는 패키지 전체 리소스보다 필요한 것만 사용하는게 적기때문이기도 한 것 같습니다. 자세한 내용은 아래 문서를 확인해보시면 좋을 것 같습니다!

 

Modular packages in AWS SDK for JavaScript | Amazon Web Services

As of December 15th, 2020, the AWS SDK for JavaScript, version 3 (v3) is generally available. On October 19th, 2020, we published the Release Candidate (RC) of the AWS SDK for JavaScript, version 3 (v3). One of the major changes in the JavaScript SDK v3 i

aws.amazon.com

v2에서는 getObject, putObject와 같은 형태로 메서드를 제공했었는데 v3부터는 GetObjectCommand,  PutObjectCommand와 같은 형태로 메서드를 제공합니다. 단순히 메서드의 형태만 바뀐 게 아니라 데이터를 가져오고 전송하는 형태도 달라졌습니다.

 

S3.GetObject no longer returns the result as a string · Issue #1877 · aws/aws-sdk-js-v3

Describe the bug I'm using the GetObjectCommand with an S3Client to pull a file down from S3. In v2 of the SDK I can write response.Body.toString('utf-8') to turn the response into a string. In v3 ...

github.com

 

v3에서부터는 buffer를 스트리밍 형태로 주고받습니다. 대표로 GetObjectCommand의 사용형태를 확인해 보겠습니다.

 

https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-s3-tutorial.html

코드를 보시다시피 GetObjectCommand의 결과로 가져온 데이터의 Body의 타입은 StreamingBlobPayloadOutputTypes 입니다. v2에서 getObject로 가져온 값의 body는 buffer였으나 v3부터는 buffer가 아니라 stereaming 형태의 타입이며  buffer 형태로 가져오기 위해서는 stream을 buffer로 변환해야 합니다. 

에피소드

로컬에서 테스를 하면서 약간의 에피소드가 있었는데 nvm으로 node버전을 변경해 가면서 테스트하다 보니 e2e테스트를 위해 띄우는 로컬 서버는 18.x로 띄우고 테스트 실행하는 node 버전은 16.x로 실행하다 보니 자꾸 127.0.0.1:4569 (serverless-offline 주소)를 연결할 수 없다고 뜨는 것이었습니다.ㅎㅎ

결론적으로는 node버전이 달랐기도 했고 v17.x 부터는 기본적으로 IPv6를 사용하기 때문에 서버가 떠있는데도 연결이 불가능했던 것입니다. 약간 바보 같은 실수이긴 하지만 그래도 나름 얻은 건 있던 것 같습니다 ㅋㅋ

 

[NodeJs] localhost가 실행되었는데 127.0.0.1 에 접속되지 않는 경우

해결 방법 (결론) 결론부터 말하자면 NodeJs 버전 17 이상부터 서버 실행시 ipv6 프로토콜을 우선적으로 사용하기 때문에 ipv4 프로토콜의 루프백 주소인 127.0.0.1 은 연결이 되지 않는 것이다. 그래서

stirringdev.tistory.com

 

3. 결론


저희는 테스트 케이스를 작성하고 있어서 버전업에 대한 대응이나 리팩토링에 대해 덜 부담스럽게 작업할 수 있었던 것 같습니다. 비즈니스 로직을 작성하는 것도 중요하지만 적절한 시기에 맞추어 유지보수를 위한 버전관리도 정말 중요합니다. 이럴 때 특히 테스트 케이스의 필요성이 더 강조되는 것 같습니다!

아직 버전 관리에 대응해야 하는 프로젝트들이 많지만... 연말인 만큼 이런 것들 후다닥 해치우고 서비스 성장을 위해 달려가야 할 것 같습니다!