TL;DR
基本上就是用 Serverless 寫一個 AWS Lambda 的 image resize function,再寫好相關的 AWS S3 trigger event 和各種 AWS 相關權限,最後 deploy 成一個 CloudFormation 然後把各種東西開好,收工!
Development
因為 image-resizer 會用到 S3,所以要在 local 開發的話可以用 serverless-offline 和 serverless-s3-local 這兩個 Serverless plugin。
首先要做個 credential 給 serverless-s3-local 用。
# ~/.aws/credentials
[s3local]
aws_access_key_id = S3RVER
aws_secret_access_key = S3RVER
接著做一份 dev 用的 serverless config。
# serverless.yml
service: image-resizer
frameworkVersion: "2"
provider:
name: aws
runtime: nodejs12.x
environment:
ENV: local
plugins:
- serverless-s3-local
- serverless-offline
custom:
s3:
host: localhost
directory: ./tmp
functions:
resize:
handler: handler.resize
events:
- s3:
bucket: images
event: s3:ObjectCreated:*
rules:
- prefix: originals/
再加上 handler.js
和 resize
function,這邊我們是用 jimp 做 resize。
最後,再把 serverless-offline 跑起來。
{
"name": "image-resize",
"scripts": {
"dev": "serverless offline"
},
}
然後傳一張照片到 s3-local 去 trigger resize funciton。
aws --endpoint http://localhost:4569 s3 cp ./image.jpg s3://images/originals/image.jpg --profile s3local
成功囉,可以在 resizeds
folder 裡看到 resized 後的 image。
Production
其實應該可以用 stage 處理不同環境,但我還是選擇先直接另外做一份 production config。
# serverless.prod.yml
service: image-resizer
frameworkVersion: "2"
provider:
name: aws
runtime: nodejs12.x
profile: yeeeeees
region: us-east-1
timeout: 20
environment:
ENV: production
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:GetObject"
Resource: "arn:aws:s3:::image-resizer/*"
- Effect: "Allow"
Action:
- "s3:PutObject"
Resource: "arn:aws:s3:::image-resizer/*"
resources:
Resources:
imageResizerBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: image-resizer
functions:
resize:
handler: handler.resize
events:
- s3:
bucket: image-resizer
event: s3:ObjectCreated:*
existing: true
rules:
- prefix: originals/
接著就可以 deploy 到 AWS 上啦。
{
"name": "2020-1224-aws-lambda-image-resize",
"scripts": {
"deploy": "serverless deploy --config serverless.prod.yml",
"logs": "serverless logs --tail --function resize"
},
}
Deploy 成功後就可以看到一堆東西XD,像是 CloudFormation。
和 Lambda function。
還有開出來的 S3 Bucket。
最後我們一樣傳一張照片到 S3 上去 trigger resize function。
aws s3 cp ./image.jpg s3://image-resizer/originals/image.jpg --profile yeeeeees
然後可以在 local 用 serverless 看 log。
也可以在 CloudWatch 上看。
以及 resize 過後的 image 啦。
成功!
Resize 一張 14.6MB 6000x4000 jpg 照片的數據如下:
- Duration: 14231.88 ms
- Billed Duration: 14232 ms
- Memory Size: 1024 MB
- Max Memory Used: 913 MB
- Init Duration: 756.24 ms
Conclusion
- Serverless 真的簡化了超級多 AWS 的設定細節,搞懂 config 後寫起來變得非~常簡單。
- Performance 應該可以再調,感覺 1x 秒有點久?然後上傳再大一點的照片 memory 還會爆掉。
- 至於費用就等之後再看囉。
- Source code 在這邊。