์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 |
- docker compose
- prod docker-compose
- aws ์ฟ ํฐ
- JPA
- docker
- jvm ๋ฐ๋ฐ๋ฅ๊น์ง ํํค์น๊ธฐ
- Kafka
- ์๋ฒ ํฐ์ง๋ ๋์ปค ์ฌ์คํ
- docker-compose kafka
- aws saa ํฉ๊ฒฉ
- AWS Certified Solutions Architect - Associate
- ํ๋ก๊ทธ๋๋จธ์ค ์ปฌ๋ฌ๋ง๋ถ
- ํ๋ก๊ทธ๋๋จธ์ค
- ์คํํ๋ ๋ฏธ์ค
- private subnet ec2 ๋ก์ปฌ ์ ์
- ํ๋ก๊ทธ๋๋จธ์ค ํฉ์นํ์์๊ธ
- docker ps -a
- ํ์ดํผ๋ฐ์ด์
- ์ ํจ์ค ๋น๋ ์ค๋ฅ
- nGrinder
- ์ ํจ์ค ์ค์ผ์ค๋ฌ
- ๋ค์ค ์ปจํ ์ด๋
- s3 log ์ ์ฅ
- redis ์กฐํ
- Entity
- Codedeploy ์ค๋ฅ
- redis ํ ์คํธ์ฝ๋
- s3 ์ด๋ฏธ์ง ์ ์ฅ
- ์๋ฐ
- s3 ์ด๋ฏธ์ง ๋ค์ด๋ก๋
- Today
- Total
๐๐ข๐๐ โ๐๐๐ ๐๐๐ก๐๐ ๐๐๐๐โง
[AWS] AWS CloudFront + Lambda@Edge ๋ฅผ ํตํ ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง ๋ณธ๋ฌธ
[AWS] AWS CloudFront + Lambda@Edge ๋ฅผ ํตํ ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง
๐คRyusun๐ค 2025. 4. 3. 11:00์ด์ ๊ธ์์ Lambda๋ฅผ ํ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ๋ฆฌ์ฌ์ด์ง ํ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ฑํ์ต๋๋ค.
https://ryusunny.tistory.com/153
[AWS] S3 + Lambda ๋ฅผ ํตํ ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง (macOS sharp ๋ชจ๋ ์ค๋ฅ, ๋ฌดํ ๋ฆฌ์ฌ์ด์ง ์ค๋ฅ)
๋ฒํท ์์ฑ, ๋๋ค ์์ฑ, IAM ์ญํ ์์ฑ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ค๋ฅธ ์ฌ์ดํธ์์ ๋ ์ ์ค๋ช ๋์ด ์์ผ๋ฏ๋ก, ์ฐธ๊ณ ํ์๋ฉด ๋๋ค.https://oliveyoung.tech/2023-05-19/aws-lambda-resize/ AWS Lambda Image Resize ๋์ ๊ธฐ | ์ฌ๋ฆฌ
ryusunny.tistory.com
ํ์ง๋ง ์ด ๋ฐฉ๋ฒ์๋ ๋ ๊ฐ์ง ๋ฌธ์ ์ ์ด ์กด์ฌํฉ๋๋ค.
- /origin ๊ฒฝ๋ก์ ์๋ณธ ์ด๋ฏธ์ง, /resized ๊ฒฝ๋ก์ ๋ฆฌ์ฌ์ด์ฆ๋ ์ด๋ฏธ์ง๊ฐ S3์ ์ ์ฅ๋์ด ์ฌ์ฉ๋์ด ์ฆ๊ฐํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ์์ ํ์ํ ์ด๋ฏธ์ง ์ฌ์ด์ฆ๊ฐ ๋ณ๊ฒฝ๋์์ ๊ฒฝ์ฐ(์: ์ธ๋ค์ผ ์ด๋ฏธ์ง ํฌ๊ธฐ ์คํ ๋ณ๊ฒฝ), ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋ค์ ํ์ํ ์ด๋ฏธ์ง์ ์ฌ์ด์ฆ์ ๋ง๊ฒ ๋ฆฌ์ฌ์ด์ง ํด์ผํฉ๋๋ค.
CloudFront์ Lambda@Edge๋ฅผ ํ์ฉํ ํด๊ฒฐ ๋ฐฉ๋ฒ
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด CloudFront์ Lambda@Edge๋ฅผ ํ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ์์ฒญ ์์ ์ ๋์ ์ผ๋ก ๋ฆฌ์ฌ์ด์งํ๋ ๋ฐฉ์์ ์ ์ฉํ ์ ์์ต๋๋ค.
- ์ฌ์ฉ์๊ฐ ํน์ ํฌ๊ธฐ์ ์ด๋ฏธ์ง๋ฅผ ์์ฒญํ๋ฉด CloudFront๊ฐ ์์ฒญ์ Lambda@Edge๋ก ์ ๋ฌํฉ๋๋ค.
- Lambda@Edge๋ S3์์ ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ ์์ฒญ๋ ํฌ๊ธฐ๋ก ์ค์๊ฐ ๋ณํํฉ๋๋ค.
- ๋ณํ๋ ์ด๋ฏธ์ง๋ CloudFront์ ์บ์ฑ๋๋ฏ๋ก ๋์ผํ ์์ฒญ์ด ๋ฐ๋ณต๋ ๊ฒฝ์ฐ Lambda@Edge์ ๋ฆฌ์ฌ์ด์ง ๊ณผ์ ์ ๊ฑฐ์น์ง ์๊ณ ์ฆ์ ์๋ตํ ์ ์์ต๋๋ค.
์ด ๋ฐฉ์์ ๋ถํ์ํ S3 ์คํ ๋ฆฌ์ง ์ฌ์ฉ์ ์ค์ด๊ณ , ํด๋ผ์ด์ธํธ์์ ์์ฒญํ๋ ์ด๋ฏธ์ง ํฌ๊ธฐ๊ฐ ๋ณ๊ฒฝ๋๋๋ผ๋ ์๋์ผ๋ก ๋์ํ ์ ์๋ ์ฅ์ ์ด ์์ต๋๋ค.
CDN(Content Delivery Network)
CDN(์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ)์ ์ ์ธ๊ณ ์ฌ๋ฌ ์์น์ ๋ถ์ฐ๋ ์๋ฒ ๋คํธ์ํฌ๋ฅผ ํตํด ์น ์ฝํ ์ธ ๋ฅผ ๋์ฑ ๋น ๋ฅด๊ณ ์์ ์ ์ผ๋ก ์ ๊ณตํ๋ ๊ธฐ์ ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์น์ฌ์ดํธ์ HTML, CSS, JavaScript, ์ด๋ฏธ์ง, ๋์์ ๋ฑ์ ์ ์ ๋ฐ ๋์ ์ฝํ ์ธ ๋ฅผ ์บ์ฑํ์ฌ, ์ฌ์ฉ์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์๋ฒ(์ฃ์ง ์๋ฒ)์์ ์๋ตํ ์ ์๋๋ก ํฉ๋๋ค.
CloudFront
Amazon CloudFront๋ AWS์์ ์ ๊ณตํ๋ CDN ์๋น์ค๋ก, ์ ์ธ๊ณ์ ์ฃ์ง ๋ก์ผ์ด์ (Edge Location)์ ํตํด ์ ์ ๋ฐ ๋์ ์ฝํ ์ธ ๋ฅผ ๋น ๋ฅด๊ฒ ๋ฐฐํฌํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
ํน์ง
- ์ ์ ๋ฐ ๋์ ์ฝํ
์ธ ์ ๊ณต
- HTML, CSS, JavaScript, ์ด๋ฏธ์ง๋ฟ๋ง ์๋๋ผ API ์๋ต, ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ ๋ฑ์ ๋์ ์ฝํ ์ธ ๋ ์ง์
- ์ ์ธ๊ณ ์ฃ์ง ๋ก์ผ์ด์
ํ์ฉ
- ์ฌ์ฉ์์ ์์ฒญ์ด ์ง์ฐ ์๊ฐ์ด ๊ฐ์ฅ ๋ฎ์ ์ฃ์ง ๋ก์ผ์ด์ ์ผ๋ก ๋ผ์ฐํ ๋จ
- ์บ์ฑ ๋ฐ ์ฑ๋ฅ ์ต์ ํ
- ์์ฒญ๋ ์ฝํ ์ธ ๊ฐ ์ด๋ฏธ ์บ์์ ์์ผ๋ฉด ์ฆ์ ์ ๊ณต
- ๋ณด์ ๊ธฐ๋ฅ ์ ๊ณต
- AWS WAF(Web Application Firewall), DDoS ๋ฐฉ์ด, ์ํธํ ๊ธฐ๋ฅ ์ง์
- ์ค๋ฆฌ์ง(Origin)๊ณผ ์ฐ๋
- Amazon S3, MediaPackage, HTTP ์๋ฒ ๋ฑ ๋ค์ํ ์ค๋ฆฌ์ง์์ ์ฝํ ์ธ ์ ๊ณต ๊ฐ๋ฅ
CloudFront์ ๋์ ๋ฐฉ์
- ์ฌ์ฉ์๊ฐ ์ฝํ ์ธ ๋ฅผ ์์ฒญํ๋ฉด CloudFront๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ค.
- ์์ฒญ๋ ์ฝํ ์ธ ๊ฐ ์ฌ์ฉ์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ฃ์ง ๋ก์ผ์ด์ ์ ์บ์๋ฅผ ํ์ธํํ ์บ์๋์ด ์์ผ๋ฉด ์ฆ์ ์ ๊ณตํฉ๋๋ค.
- ์บ์์ ์๋ ๊ฒฝ์ฐ, CloudFront๋ ์ค๋ฆฌ์ง(S3)์์ ๋ฑ์์ ์ฝํ ์ธ ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
- ์ฃ์ง ๋ก์ผ์ด์ ์ ๊ฐ์ ธ์จ ์ฝํ ์ธ ๋ฅผ ์ผ์ ๊ธฐ๊ฐ ๋์ ์ฝํ ์ธ (์บ์) ์ ์ฅํ์ฌ ์ดํ ์์ฒญ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
CloudFront์ ์ฅ์
- ์ง์ฐ ์๊ฐ ๊ฐ์
- ์ฌ์ฉ์์ ๊ฐ๊น์ด ์์น์์ ์ฝํ ์ธ ์ ๊ณต
- ๋คํธ์ํฌ ๋ถํ ๋ถ์ฐ
- ์ฌ๋ฌ ์ฃ์ง ๋ก์ผ์ด์ ์ ๋ถ์ฐํ์ฌ ์๋ฒ ๋ถํ ๊ฐ์
- ๋ณด์ ๊ฐํ
- AWS WAF, DDoS ๋ฐฉ์ด, ์ํธํ ๋ฑ ๋ค์ํ ๋ณด์ ๊ธฐ๋ฅ ์ ๊ณต
- ๋น์ฉ ์ ๊ฐ
- ์๋ณธ ์๋ฒ(์ค๋ฆฌ์ง)๋ก์ ์์ฒญ ํ์๋ฅผ ์ค์ฌ ํธ๋ํฝ ๋น์ฉ ์ ๊ฐ
- ๋์ ํ์ฅ์ฑ
- ํธ๋ํฝ ๊ธ์ฆ์๋ ์์ ์ ์ธ ์๋น์ค ์ ๊ณต
Lambda@Edge
Lambda@Edge๋ AWS Lambda์ ํ์ฅ๋ ์ปดํจํ ์๋น์ค๋ก, CloudFront์ ์ฃ์ง ๋ก์ผ์ด์ (Edge Location)์์ ์คํ๋๋ ํจ์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด Lambda ํจ์๊ฐ ์ ์ธ๊ณ์ ์ฃ์ง ๋ก์ผ์ด์ ์ ๋ณต์ฌ๋์ด ๋ฐฐํฌ๋๋ฉฐ, ์ฌ์ฉ์๋ ๊ฐ์ฅ ๊ฐ๊น์ด ์ฃ์ง ์๋ฒ์์ ์คํ๋๋ Lambda ํจ์๋ฅผ ์ด์ฉํ ์ ์์ต๋๋ค.
์ด ๋ฐฉ์์ ์น ์ฝํ ์ธ ์ ์ง์ฐ ์๊ฐ์ ์ค์ด๊ณ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐ ์ ์ฉํ๋ฉฐ, ์ด๋ฏธ์ง ๋ณํ, ๋ณด์ ํค๋ ์ถ๊ฐ, ์ฌ์ฉ์๋ณ ์๋ต ์ต์ ํ ๋ฑ ๋ค์ํ ์ฉ๋๋ก ํ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋์ ํ์๋ Lambda@Edge + Cloudfront๋ฅผ ํ์ฉํ์ฌ ์ค์๊ฐ์ผ๋ก ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์งํ๋ ๊ฐ๋ฅ์ ๊ตฌํํ์ต๋๋ค.
CloudFront, Lambda@Edge ์ค์
๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํ ์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง์ ํด๋ณด์
์๋ ํ์ธ์! ํฌ๋ชฝ์ ํธ๋ฅธํผ, ๋ ์ค๋ฅด๋ ๋ธ๋ฃจ์นฉ Blue(๋ธ๋ฃจ)์ ๋๋ค.
blog.kmong.com
์ฐธ๊ณ ํ ๋ธ๋ก๊ทธ์ ๋๋ค. ํด๋น ๋ธ๋ก๊ทธ์ ์ค์ ๊ณผ์ ์ ๋ํ ์์ธํ ์ค๋ช ์ด ๋์์์ต๋๋ค.
cloudwatch ๋ก๊ทธ๋ฅผ ์ํ ๋ก๊ทธ ์ ์ฑ ์ ํฌํจํ ์ ์ฑ ์ ๋๋ค.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LambdaEdgePermissions",
"Effect": "Allow",
"Action": [
"lambda:GetFunction",
"lambda:EnableReplication*",
"cloudfront:UpdateDistribution",
"s3:GetObject",
"s3:ListBucket",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
Lambda ํจ์ ์ฝ๋
const sharp = require('sharp');
const aws = require('aws-sdk');
const s3 = new aws.S3({ region: 'ap-northeast-2' });
const BUCKET = 'iruyeon';
exports.handler = async (event, _, callback) => {
const { request, response } = event.Records[0].cf;
/** ์ฟผ๋ฆฌ ์ค๋ช
* w : width
* h : height
* f : format
* q : quality
* t : type (contain, cover, fill, inside, outside)
*/
const querystring = request.querystring;
const searchParams = new URLSearchParams(querystring);
if (!searchParams.get('w') && !searchParams.get('h')) {
console.log("No resizing parameters found. Returning original response.");
return callback(null, response);
}
const { uri } = request;
const match = uri.match(/\/?(.*)\.(.*)/);
if (!match) {
console.error("Invalid URI format:", uri);
return callback(null, response);
}
const [, imageName, extension] = match;
const width = parseInt(searchParams.get('w'), 10);
const height = parseInt(searchParams.get('h'), 10);
const quality = parseInt(searchParams.get('q'), 10) || DEFAULT_QUALITY;
const type = searchParams.get('t') || DEFAULT_TYPE;
const f = searchParams.get('f');
const format = (f === 'jpg' ? 'jpeg' : f) || extension;
try {
const s3Object = await getS3Object(s3, BUCKET, imageName, extension);
const resizedImage = await resizeImage(s3Object, width, height, format, type, quality);
response.status = 200;
response.body = resizedImage.toString('base64');
response.bodyEncoding = 'base64';
response.headers['content-type'] = [{ key: 'Content-Type', value: `image/${format}` }];
response.headers['cache-control'] = [{ key: 'cache-control', value: 'max-age=31536000' }];
return callback(null, response);
} catch (error) {
console.error("Processing error:", error);
return callback(error);
}
};
const DEFAULT_QUALITY = 80;
const DEFAULT_TYPE = 'contain';
async function getS3Object(s3, bucket, imageName, extension) {
const key = decodeURI(`${imageName}.${extension}`);
try {
const s3Object = await s3.getObject({ Bucket: bucket, Key: key }).promise();
return s3Object;
} catch (error) {
console.error("s3.getObject error:", error);
throw error;
}
}
async function resizeImage(s3Object, width, height, format, type, quality) {
try {
const resizedImage = await sharp(s3Object.Body)
.resize(width, height, { fit: type })
.toFormat(format, { quality })
.toBuffer();
return resizedImage;
} catch (error) {
console.error("resizeImage error:", error);
throw error;
}
}
์ดํ, CloudFront Domain Name์ผ๋ก ์ ์ํ์ฌ ์ํ๋ query๋ฅผ ์ค์ ํ x-cache ํค๋๋ฅผ ํ์ธํฉ๋๋ค.
x-cache ํ์ธํ๋ ๋ฐฉ๋ฒ (ํฌ๋กฌ)
1. ๊ฐ๋ฐ์ ๋๊ตฌ ์ด๊ธฐ (F12 ๋๋ Ctrl + Shift + I (Mac: Cmd + Option + I)
2. ์๋จ ๋ฉ๋ด์์ Network(๋คํธ์ํฌ) ํด๋ฆญ
3. ์๋จ์ Img(์ด๋ฏธ์ง) ํํฐ ํด๋ฆญ
4. ํด๋น ์ด๋ฏธ์ง ์ ํ
5. Headers(ํค๋) ํญ ํด๋ฆญ
6. x-cache ํญ๋ชฉ์ ์ฐพ์ผ๋ฉด, ํด๋น ๊ฐ์ด Hit/Miss/Expired์ธ์ง ํ์ธ ๊ฐ๋ฅ
x-cache ๊ฐ์ ์๋ฏธ
Hit from cloudfront | CloudFront ์บ์์์ ์ ๊ณต๋จ (์บ์ฑ ์ฑ๊ณต) |
Miss from cloudfront | CloudFront ์บ์์ ์์ (์ ์์ฒญ) |
Expired from cloudfront | ์บ์ ๋ง๋ฃ ํ ์ ์์ฒญ ์ํ |
RefreshHit from cloudfront | ์บ์๋ ๊ฐ์ฒด๋ฅผ ์๋ก๊ณ ์นจ |
[์๋ ๋น๊ต]
์ต์ด ์์ฒญ ์ CloudFront์ ์บ์๊ฐ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก, ์ค๋ฆฌ์ง์ธ S3์์ ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ Lambda@Edge๊ฐ ๋ฆฌ์ฌ์ด์ง์ ์ํํ ํ ์ ์ ํ ์ด๋ฏธ์ง๋ฅผ ๋ฐํํฉ๋๋ค.
์ดํ ๋์ผํ ์์ฒญ์ด ๋ค์ด์ค๋ฉด CloudFront์ ์บ์ฑ๋ ์ด๋ฏธ์ง๋ฅผ ์ฆ์ ์ ๊ณตํ์ฌ ์๋ต ์๊ฐ์ ๋จ์ถํฉ๋๋ค.
[์ฐธ๊ณ ]
https://wired.company/blog_original/?bmode=view&idx=15848347
CloudFront์ AWS Lambda@edge๋ฅผ ํ์ฉํ ์ด๋ฏธ์ง ์ต์ ํ : ์์ด์ด๋์ปดํผ๋
์๋ ํ์ธ์. ์ ๋ ์์ด์ด๋์ปดํผ๋ ๊ฐ๋ฐํ์ ๋๋ค.Kemi์์ ๋ฆฌ์ฌ์ด์ง๋ ์ด๋ฏธ์ง๋ฅผ ๋ฐ์ ๋น ๋ฅด๊ฒ ์ปจํ ์ธ ๋ฅผ ๋ก๋ฉํ ์ ์๋๋ก ๊ตฌํํ๋ ๊ฒฝํ์ ๊ณต์ ํ๊ณ ์ ํฉ๋๋ค.๋ฌธ์ ์ธ์ "์ปจํ ์ธ ๋ฅผ ๋น ๋ฅด๊ฒ ๋ณด์ฌ์ฃผ
wired.company
https://medium.com/@115taegyeong/image-resizing-d4cea1b1ba55
Lambda@Edge Image Resizing
์ด๋ฏธ์ง ๋ฆฌ์ฌ์ด์ง&ํ๋งท๋ณํ์ ํตํ ์ฑ๋ฅ ๊ฐ์
medium.com