티스토리 뷰
이전 글들은 이 글을 쓰기위한 빌드업이 었다.
1. AWS S3와 CloudFront 연동 끝까지 가보기
3. Go + serverless framework로 Lambda 관리하기
4. 꼭 읽어줬으면 하는 AWS Lambda@Edge의 특이 사항들 정리
개인적으로는 Lambda@Edge를 시작하기전에 4번은 꼭 훑고 갔으면 좋겠다.
1번 글의 마치며에서도 언급한 내용이지만,
이미지가 아직 CloudFront(CDN)에 등록되지 않았을 경우 첫 로딩에 문제가 발생할 수 있다.
그리고 그 문제는 이미지의 크기가 커질수록, 더 커질 것이다.
그래서 이미지의 사이즈를 작게 만드는 과정이 필요하다.
(리사이징이든, 확장자 변환이든 여러가지 방법이 있다)
하지만 원본 이미지를 S3에 저장하기 전에 변환하게 되면, 원본 이미지가 손실되기 때문에 문제가 발생할 수 있다.
(서비스 운영 중에는 원본 이미지를 사용해야할 경우가 언제 생길지 모른다)
그래서 사용자가 이미지를 업로드하는 아래의 프로세스에서 request 부분은 손댈 수 없다.
그래서 여기서 손댈 부분은 origin response다.
앞으로 할 내용을 요약해보면,
1. origin(S3)에서 CloudFront로 응답이 나가는 부분을 캐치
2. 이벤트 정보를 바탕으로 이미지를 가져옴
3. webp 형식으로 변환
4. CloudFront에 base64 형식으로 전달
위 방식으로 진행될 것이다.
AWS 리소스들은 1. AWS S3와 CloudFront 연동 끝까지 가보기 이 글에서 썼던 것들을 모두 재활용할 것이다.
그리고, 앞서 언급한 빌드업이 차례대로 사용될 예정이다.
결론적으로 이야기하면 아래와 같은 프로세스로 동작하게 될 것이다.
일단 Lambda를 구성해야하므로 serverless.yml부터 작성해보자.
serverless.yml
람다를 수동으로 연결하는 방식도 있다. 하지만 재배포할 때 번거로워지므로 코드베이스로 관리하게끔 했다.
service: edge
frameworkVersion: '3'
plugins:
- serverless-plugin-common-excludes
- serverless-plugin-include-dependencies
- serverless-lambda-edge-pre-existing-cloudfront
provider:
name: aws
runtime: nodejs18.x
architecture: x86_64
region: us-east-1
memorySize: 256
timeout: 10
logRetentionInDays: 30
iam:
role: arn:aws:iam::301591718339:role/test-edge-role
functions:
imageConverter:
name: webpConverter
handler: webpConverter.main
events:
- preExistingCloudFront:
distributionId: E2xxxxx // 대문자로 시작하는 cloudfront id
eventType: origin-response
pathPattern: '*'
includeBody: false
플러그인들 중 가장 중요한건 serverless-lambda-edge-pre-existing-cloudfront이다.
events에 preExistingCloudFront를 사용할 수 있게 해주는 플러그인이다.
매번 수동으로 재배포하기 싫으면 이 기능을 사용하는게 좋다.
나머지는 자동으로 불필요/필요한 패키지들을 제외/포함하는 플러그인들이다.
모두 설치해주자.
npm install serverless-lambda-edge-pre-existing-cloudfront
npm install serverless-plugin-common-excludes
npm install serverless-plugin-include-dependencies
이벤트 처리
코드로 가기전에 이벤트가 어떤형식으로 날아오는지 알아야 데이터를 가져올 수 있다.
Records[0].cf.request.origin.s3.domainName에서 S3의 경로를 가져올 수 있다.
{
config: {
...
},
request: {
...
uri: '/background.png'
},
response: {
...
},
status: '200',
statusDescription: 'OK'
}
}
그리고, Records[0].cf.request.uri 에서 파일 이름인 uri를 가져와야한다.
{
clientIp: '',
headers: {
'x-forwarded-for': [ [Object] ],
'user-agent': [ [Object] ],
via: [ [Object] ],
'accept-encoding': [ [Object] ],
host: [ [Object] ]
},
method: 'GET',
origin: {
s3: {
authMethod: 'none',
customHeaders: {},
domainName: 'testbed-image-bucket.s3.ap-northeast-2.amazonaws.com',
path: ''
}
},
querystring: '',
uri: '/background.png'
}
함수 코드
이미지 변환 라이브러리는 sharp를 사용했다.
내 환경은 WSL이기 때문에 아래와 같이 설정
npm install --os=linux --cpu=x64 sharp
window에서 sharp를 사용했으면 배포 전에 위 스크립트나 다른 방법을 통해 node_modules를 수정해줘야 한다.
OS에 따라 바뀌는게 있는 것 같다.
함수 코드는 GitHub에서 확인하자.
https://github.com/imsosleepy/serverless-lambda/blob/main/edge/webpConverter.js
코드는 앞서 언급했듯이 들어오는 이미지를 400x400 webp로 변환해서 base64로 인코딩한 후 reponse에 실어 cloudfront로 보내주는 코드다.
결과 화면
Response headers를 보면 Content-Type이 webp로 설정된 것을 확인할 수 있다.
이미지 크기도 원본 1MB 였는데 154kb로 줄어든 걸 확인할 수 있다.(초기 요청시)
GitHub
https://github.com/imsosleepy/serverless-lambda/tree/main/edge
마치며
회사 컨플루언스에 작성한 내용을 각색해서 다시 올린 글이다.
완성본은 on-the-fly 방식이지만, 리뷰하는 형식으로 따라만들다보니 내용이 많이 축약됐다.
처음에는 Go로 작성했는데, Lamda@Edge에는 Go를 사용할 수 없어 nodejs로 변경했다.
솔직히 쿠버네티스가 너무 부담스러워서 빙빙 돌았는데,
지인들과 이런저런 이야기를 나눠보니 일단 시작하는게 중요한 것 같다는 결론을 내렸다.
이제 쿠버네티스를 진짜 손대야 할 때가 온 것 같다.
'개발 > AWS' 카테고리의 다른 글
AWS S3 버킷을 퍼블릭하게 사용하기 : SpringBoot에서 퍼블릭하게 업로드하기 (0) | 2024.03.08 |
---|---|
AWS EC2에 SSL/TLS(HTTPS) 인증서 적용기 (0) | 2024.01.26 |
꼭 읽어줬으면 하는 AWS Lambda@Edge의 특이 사항들 정리 (0) | 2024.01.16 |
Go + serverless framework로 Lambda 관리하기 (0) | 2024.01.12 |
AWS S3와 CloudFront 연동 끝까지 가보기 (1) | 2024.01.05 |
- Total
- Today
- Yesterday
- 스프링부트
- serverless
- springboot
- elasticsearch
- CloudFront
- S3
- ChatGPT
- openAI API
- OpenAI
- 람다
- Elastic cloud
- GIT
- AOP
- AWS EC2
- docker
- Kotlin
- 티스토리챌린지
- JWT
- 후쿠오카
- OpenFeign
- Log
- MySQL
- terraform
- EKS
- Spring
- cache
- 오블완
- AWS
- lambda
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |