More Related Content
Similar to Lambda@Edge를통한멀티리전기반글로벌트래픽길들이기::이상현::AWS Summit Seoul 2018
Similar to Lambda@Edge를통한멀티리전기반글로벌트래픽길들이기::이상현::AWS Summit Seoul 2018 (20)
More from Amazon Web Services Korea
More from Amazon Web Services Korea (20)
Lambda@Edge를통한멀티리전기반글로벌트래픽길들이기::이상현::AWS Summit Seoul 2018
- 1. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
이상현, Vingle
Lambda@Edge를 이용한
Serverless로의 Migration & Multi-Region
- 2. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
이상현 Kurt Lee
Technical Leader, Vingle Inc
kurt@vingle.net
https://github.com/breath103
- 3. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Vingle, Interest Network
- 4. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
- 5. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Monthly Active User
Monthly Page View
App Store Rating
5 Milion
3 Billion
4.7
- 6. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Lambda@Edge
CDN + Edge Computing
Microservice
Lambda + API Gateway
Serverless
Microservice
Gradual
Migration
Multi-Region
(Cache + Edge)
Agenda
- 7. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
다루지 않는 내용
1. Microservice / monolith의 개념
2. 왜 Microservice로 옮겼나
3. 왜 Serverless로 옮겼나
4. API Gateway / Lambda / S3 / Athena 상세 설명
5. CI / CD 상세 설명
- 8. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Serverless
Microservice
Gradual
Migration
1. Legacy Application이 있고,
2. 새로운 Application이 있고,
3. 새로운 Application으로 기능을 하나씩 옮겨갈때
4. 어떻게 트래픽을 지능적으로 (어떤 Application으로 보낼지 판단해서)
5. 안정적으로, 점진적으로 Routing 할 것 인가?
6. 사람 4명으로, 기능을 계속 추가하면서
- 9. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Previously…
- 10. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
US-EAST-1
- 11. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
Notifications
Card
QnA
1. Microservice들의 응답을 조합 + Routing (API Gateway)
2. 아주 기본적인 유저 인증 (JWT ▷ user_id)
3. 옮기기 어려운 것들 (옛날 RDS라던가.. devise 라던가..)
US-EAST-1
- 12. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
1) 요청이 들어옴
2) 유저 인증
JWT ➡ userId
3) Microservice로 보냄
/me/notifications ➡ getNotifications(userId)
4) 응답 return
- 13. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Rails가 하는 일을 Microservice로 구현
(Lambda + API Gateway)
- 14. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
aaa.excute-api.us-east-1.com
이걸 어떻게 배포하지?;;
(천천히?)
- 15. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
aaa.excute-api.us-east-1.com
- 16. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
aaa.excute-api.us-east-1.com
• API Gateway를 target으로 지정 못
함
• URL Pattern으로만 routing 가능
- 17. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
aaa.excute-api.us-east-1.com
• Multiple Origin이 지원 안됨
- 18. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
aaa.excute-api.us-east-1.com
• Domain 이외의 정보는 모두 사용
불가
확 Reverse Proxy(Nginx) Cluster를 만들어버릴까...
- 19. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
Nginx Cluster
- 20. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Homo Faber : "Working Man"
Animal Laborans: "Working Animal"
Animal Laborans란 이름 그대로, 기계적이고 일상적으로 일을 하는 가축과 같은 사람을 뜻한다.
아렌트는 오펜하이머가 원자폭탄을 "달콤한 문제" 라고 표현하는 것이나, 아이히만(유대인 학살 시스템
설계자)이
얼마나 가스실을 "효율적"으로 만드는데 집착했는지 에서 이 이미지를 찾았다. 그들은 뭔가가 돌아가게
하는대에(making it work)만 몰입하며, 그로써 "일 그 자체"를 "일의 끝"으로 삼는다.
Homo Faber는 이와 대조되는 종류의 인간을 뜻한다. 원어는 라틴어로 "만드는 사람" 이지만, 아렌트는
좀더 분명한 이미지를 부여했다. 그녀에 따르면 Homo Faber는 노동과 노력의 판단자(Judge)이다. 이때
인간은 일에 몰입하는 존재이지만, 동시에 도덕과 판단의 주체이다. 이들은 뭔가를 생산하기를 멈추고,
다른 판단자들과 자신들이 하는 일에 대해 토론하고 판단할수 있다.
그렇기에, Animal Laborans이 "How"를 물을때 Homo Faber는 "Why"를 묻는다
- Richard Sennett, The Craftsman
문장이 길어지면 안읽는 사람들을 위한 4줄 요약:
1. 인간은 원래 만드는 것에 몰입하는 존재다
2. 몰입해서 일만하면 원자폭탄이나 가스실을 만든다
(그리고 심지어 너무 만족스러워한다)
3. 그러니 지금 하는일을 왜 하는지 판단하면서 해라
4. 안그러면 가축이랑 다른게 뭐냐
- 21. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CDN
Load
Balancer
EC2 Fleet
(Nginx + Rails)
Microservices
(Lambda + DynamoDB)
Feed
Interest
US-EAST-1
Notifications
Card
QnA
API Edge
(API Gateway + Lambda)
Nginx Cluster
1. Serverless로 가야함
2. 천천히 migration 하려면 reverse proxy가 필요
3. reverse proxy cluster를 앞에 만들자?
?? Serverless로 가려고 Cluster를 하나 더 만들자 ??
- 22. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
function proxy(req: Request) {
if (req.url == "/api/me/notifications" &&
req.headers.get("accept") == "application/json") {
return sendToAPIEdge(req);
} else {
return sendToRails(req);
}
이걸 Serverless로 돌리고 싶을 뿐인데..
- 23. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
때는 11월...
Lambda@Edge?
- 24. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Origi
n
America
Asia
Europe
Africa
- 25. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Lambda@Edge
1. Request에 따라 다른 Origin으로 보낸다거나
2. Request에 따라 CDN에서 바로 응답을 준다거나
3. CDN Cache에 넣기 전에 Origin Response를 변조한다던가
4. Cache된 Reponse를 주기전에 변조한다던가
- 26. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Reverse Proxy
(Serverless)
- Multiple Origin Servers
- Dynamic Routing
- Caching
- Managed Reverse Proxy
…
Web App
(Simple)
- CORS (OPTION request)
- 404 / 500 / down
- Redirection (www -> m)
- IP Blocks
…
- 27. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices
(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
CDN
- 28. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices
(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
CDN
- 29. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
import {
CustomOrigin, getRequestHeader, OriginRequest, OriginRequestEvent
} from "../../request";
// Origin-Request Event Handler
export function handler(request: OriginRequest) {
if (
request.uri === "/api/me/notifications"
) {
const apiEdge: CustomOrigin = {
port: 443,
domainName: "xxxxxxx.execute-api.us-east-1.amazonaws.com",
protocol: "https",
path: "/prod",
sslProtocols: ["TLSv1", "TLSv1.1"],
readTimeout: 30,
keepaliveTimeout: 30,
customHeaders: {},
};
request.origin = { custom: apiEdge };
// Override host to let APIGateway swallow this
request.headers.host = [
{ key: "host", value: apiEdge.domainName }
];
}
return request;
}
Proof of concept
API Edge로 보낼수 있는 URL인지
검사
맞으면 Request의 Origin을
API Edge로 변경
request를 return
- 30. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
그때는 몰랐습니다. 이게 겨우 시작일줄은...
- 31. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
1. The ultimate goal of backend team is to make Vingle service better. Anything “we” can do to
accomplish that is our job
2. Primary goal of backend team is to provide manageable, reliable, scalable, extensible backend
service.
3. There is no such a thing as “Perfect Architecture / Library / Pattern that solve every problems.”
Design Pattern is just a pattern. Remember "To a man with a hammer, everything looks like a nail."
Mixing patterns, or being untraditional, or being heretic is perfectly fine if it solves the given
problem and the situation.
4. Question all the rules and traditions. Test them and rewrite them if you can.
5. Get rid of things to “manage” as much as possible. Our time can be much more valuable when it’s
spent on building things, not monitoring and managing. Let machines do that.
6. API is the product we build, frontend developers are our customer.
7. “Any organization that designs a system will produce a design whose structure is a copy of the
organization's communication structure.”
Fundamental principles of our team
“관리” 해야 하는것을 최대한 없애라.
우리의 시간은 뭔가를 만들기 위해 쓰여질때 가장 가치있다.
“관리” 는 기계가 하게 해라.
Lint / Test / Deployment / Monitoring / Alert
- 32. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
문제 1) Lambda@Edge는 반드시 lambda의 “version”을 명시해야함.
arn:xxx:xxx:function-name:$LATEST (X)
arn:xxx:xxx:function-name:98 (✓)
즉 새로운 lambda 버젼을 올릴때마다, Cloudfront도 배포해야함
- 33. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Repository Setup
vingle-edge
Origin-Request
요청에 따라, 어떤 Origin으로 보낼지 분기 / 결정
Viewer-Request
요청에 따라, Edge에서 응답을 만들어 주는경우
function handler(request: OriginRequest):
OriginRequest
function handler(request: OriginRequest):
OriginRequest | OriginResponse
CloudFront Distribution
기본 Origin (Rails ELB) / Cache Policy
/ Cookie, Header forwarding.. etc
Continuous Integration
Push
1. Test
2. Lint
3. 새로운 Lambda Version을 올리고,
4. CloudFront에 해당 Lambda Version을 연결
- serverless-lambda-version plugin
- 34. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
예상치 못한 여정: Monitoring
- 35. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Lambda@Edge
1) Lambda@Edge는 원본 Lambda를 모든
CloudFront region에 복사하는식으로 동작
함
2) 각각의 복사본 이름은
(원본region).(원본 이름):(version)
3) 이때 복사된 Lambda각각은 일반적인
Lambda와 다를바 없이 CloudWatch 제공.
4) AWS console에서는 안보이는데,
filter 켜면 접근 가능
- 36. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Lambda@Edge - CloudWatch
- 37. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
CloudFront - Basic
1) BytesUploaded
2) BytesDownloaded
3) Requests
4) TotalErrorRate
5) 5xxErrorRate
6) 4xxErrorRate
Cloudwatch 뭔가...더...자세히...보고싶다...
(1) Client별로 요청을 얼마나 보내는지?
(2) Host (www / m / api) 별로 얼마나?
(3) URL 별로?
(4) Language 별로?
(5) 한국에서 영어로 쓰는 사람은 얼마나 있지?
- 38. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
1) Raw level log를 CSV로 S3에 쌓아주는 기능이 있
음
2) S3? Athena로 쿼리하면 되겠네?
3) 근데 S3에 만들어질때 파일 이름이 엉망이라
Athena Table에서 파티션이 안됨..
4) S3에 파일이 만들어질때마다
파일 이름을 정리해서 S3에 다시 올리면?
5) 그것도 serverless로 만들어야지..
6) S3 -> Lambda Trigger -> S3 Upload -> Athena
Partition..
7) 자세한 이야기는 https://bit.ly/2Jc8UpO
CloudFront - Advanced
- 39. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
SELECT
(year || month || day) as time,
hostheader, count(1) as count
FROM vingle_edge.cloudfront_logs
WHERE
(year || month || day)
> date_format(CURRENT_TIMESTAMP - interval '6' DAY, '%Y%m%d')
GROUP BY 1, 2
ORDER BY 1, 2 DESC
지난 6일동안 domain 별로 요청량 총
합
SELECT
uri, count(1) as count
FROM vingle_edge.cloudfront_logs
WHERE
uri LIKE '/posts/'
AND hostheader = 'https://www.vingle.net'
GROUP BY 1, 2
ORDER BY 1, 2 DESC
LIMIT 100
www.vingle.net/posts/:postId
의 총 요청량 기준 Top 100
- 40. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Dashboard
- 41. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Deployment
- 42. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices
(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
- 43. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
그런데 만들고 보니..
- 44. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices
(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
- 45. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
Sitemap Service
(robots.txt + sitemaps)
S3 Bucket
(Lambda + SQS)
CloudFront
s3.bucket.com/bucket
Google 왈:
- Sitemap은 반드시 같은 도메인에서 나와야함
- www.vingle.net/robots.txt + sitemap.s3.com/sitemap.xml (✕)
- www.vingle.net/robots.txt + www.vingle.net/sitemap.xml (✓)
- 46. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
Sitemap Service
(robots.txt + sitemaps)
S3 Bucket
(Lambda + SQS)
CloudFront
s3.bucket.com/bucket
- 47. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
import {
createHeaders, CustomOrigin, getRequestHeader,
OriginRequest, OriginRequestEvent, S3Origin,
} from "../../request";
// Origin-Request Event Handler
export function handler(request: OriginRequest) {
const host = getRequestHeader(request, "Host") || "";
if (
(["www.vingle.net", "m.vingle.net"].indexOf(host) > -1)
&& (
request.uri === "/robots.txt" ||
request.uri.startsWith("/sitemaps/")
)
) {
const s3Origin: S3Origin = {
authMethod: "none",
customHeaders: {},
domainName: "vingle-sitemap-prod.s3.amazonaws.com",
path: `/${host}`,
};
request.origin = { s3: s3Origin };
request.headers = Object.assign(
request.headers,
createHeaders([{ key: "host", value: s3Origin.domainName }])
);
return request;
}
return request;
Sitemap / robots.txt 관련된 요청이
면
Origin을 S3로 설정
- 48. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
구글에서 잘 읽어가고 있나?
SELECT
(year || month || day || hour || ‘:00:00’) as time,
status,
count(1) as count
FROM vingle_edge.cloudfront_logs
WHERE
(year || month || day)
> date_format(CURRENT_TIMESTAMP - interval '6' DAY, ‘%Y%m%d’)
BY hostheader = 'www.vingle.net'
BY useragent LIKE '%Googlebot/2.1%'
BY uri LIKE '%/sitemaps_v2/%'
GROUP BY 1, 2
ORDER BY 1, 2 DESC
- 49. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
- 50. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Multi-Region
- 51. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
Sitemap Service
(robots.txt + sitemaps)
S3 Bucket
(Lambda + SQS)
CloudFront
1. 이러면 API Edge는 구성요소가 lambda + API Gateway가 끝이네?
2. 그러면 다른 region에 올려도 되지 않나?
npm run deploy — --region=ap-northeast-2 하면 끝인데
3. traffic을 region에 따라 다르게 보내야 하는데?
아 lambda@edge에서 routing 하면 되겠네?
4. 특정 region의 lambda가 outage나거나 하면
lambda@edge에서 다른 region으로 보낼수 있고?
5. 일반 유저들은 사용할때 속도가 더 빨라질꺼고?
6. 새로운 기능을 region별로 배포해서
테스트 해볼수도 있으니까 risk도 적어지고?
- 52. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
US-EAST-1
Load Balancer
(Lambda + DynamoDB)
Microservices(Nginx + Rails)
EC2 Fleet
(API Gateway + Lambda)
API Edge
Sitemap Service
(robots.txt + sitemaps)
S3 Bucket
(Lambda + SQS)
CloudFront
1. Multi Region이 좋은건 다들 아는데, 왜 안하지?
2. 관리가 너무 어려우니까
3. Serverless는 기본적으로 관리할게 없는데?
4. 오잉?
- 53. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
Legacy
Load Balancer
Legacy
Rails Application
Microservices
US-EAST-1
API Edge
(API Gateway + Lambda)
- 54. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
AP-NORTHEAST-2
CloudFront
Legacy
Load Balancer
Legacy
Rails Application
Microservices
US-EAST-1
API Edge
(API Gateway + Lambda)
- 55. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
AP-NORTHEAST-2
API Edge
(API Gateway + Lambda)
CloudFront
Legacy
Load Balancer
Legacy
Rails Application
Microservices
US-EAST-1
API Edge
(API Gateway + Lambda)
- 56. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
us-east-1 ——> aaaa.execute-api.us-east-1.amazonaws.com/prod
ap-northeast-2 ——> bbbb.execute-api.ap-northeast-2.amazonaws.com/prod
us-west-1 ——> cccc.execute-api.us-west-1.amazonaws.com/prod
- 57. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
export const Endpoints = {
["us-east-1"]: {
port: 443,
domainName: "aaaa.execute-api.us-east-1.amazonaws.com",
protocol: "https",
path: "/prod",
sslProtocols: ["TLSv1", "TLSv1.1"],
readTimeout: 30,
keepaliveTimeout: 30,
customHeaders: {},
} as CustomOrigin,
["ap-northeast-2"]: {
port: 443,
domainName: "bbbb.execute-api.ap-northeast-2.amazonaws.com",
protocol: "https",
path: "/prod",
sslProtocols: ["TLSv1", "TLSv1.1"],
readTimeout: 30,
keepaliveTimeout: 30,
customHeaders: {},
} as CustomOrigin,
["us-west-1"]: {
port: 443,
domainName: "cccc.execute-api.us-west-1.amazonaws.com",
protocol: "https",
path: "/prod",
sslProtocols: ["TLSv1", "TLSv1.1"],
readTimeout: 30,
keepaliveTimeout: 30,
customHeaders: {},
} as CustomOrigin,
const APIEdgeRegionMap
= new Map<string, CustomOrigin>([
["ap-northeast-1", Endpoints["ap-northeast-2"]],
["ap-northeast-2", Endpoints["ap-northeast-2"]],
["ap-south-1", Endpoints["ap-northeast-2"]],
["ap-southeast-1", Endpoints["ap-northeast-2"]],
["ap-southeast-2", Endpoints["ap-northeast-2"]],
["ca-central-1", Endpoints["us-east-1"]],
["cn-north-1", Endpoints["us-east-1"]],
["eu-central-1", Endpoints["us-east-1"]],
["eu-west-1", Endpoints["us-east-1"]],
["eu-west-2", Endpoints["us-east-1"]],
["eu-west-3", Endpoints["us-east-1"]],
["sa-east-1", Endpoints["us-east-1"]],
["us-east-1", Endpoints["us-east-1"]],
["us-east-2", Endpoints["us-east-1"]],
["us-west-1", Endpoints["us-east-1"]],
["us-west-2", Endpoints["us-east-1"]],
]);
- 58. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
import {
CustomOrigin, getRequestHeader, OriginRequest, OriginRequestEvent
} from "../../request";
// Origin-Request Event Handler
export function handler(request: OriginRequest) {
if (
request.uri === "/api/me/notifications"
) {
const endpoint =
APIEdgeRegionMap.get(process.env.AWS_REGION as string)
|| APIEdgeEndpoints["us-east-1"];
// If missing region, which should not happen anyway,
// send it to us-east-1
API Edge로 보낼수 있는 URL인지
검사
request를 return
현재 Lambda@Edge & Cloudfront
의 region
(process.env.AWS_REGION)
- 59. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
서울에서의 속도 개선
GET /cards/:cardId/likes
- 카드를 좋아요 한 사람 목록
- 유저가 새로 좋아요를 하지 않는 이상 캐쉬된 결과가 나옴. 10~20ms 이내
- 하지만 Seoul -> Virginia 최소 Latency가 100ms~200ms…
300ms ➡ 70ms
- 60. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
www.vingle.net
m.vingle.net
api.vingle.net
CloudFront
AP-NORTHEAST-2
CloudFront
US-EAST-1
API Edge
(API Gateway + Lambda)
API Edge
(API Gateway + Lambda)
- 61. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
- 62. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
삽질을 피하기 위해서 반드시 필요한,
하지만 경험해보지 않으면 모르는 팁들
- 63. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
1. CloudFront는 Origin에서 오는 Error Response를
기본적으로 캐쉬한다.
분명히 아이디 / 비밀번호가 맞는데
로그인이 되다 안되다 해요
- 64. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
2. Lambda@Edge에서 Request Header에 접근하려면
Cloudfront에서 이걸 whitelist 해야한다
- 65. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
3. Lambda@edge는 Production환경을 디버깅 하기 어렵다.
if (
req.method === "GET"
&& regex(//api/questions/(S*)+/answers/(S*)/g, req.uri)
)
- 66. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Unit Test는 필수
it("should send request to vingle-api-edge", async () => {
const tester = async (method: string, uri: string, accept: string) => {
expect((await handler(createRequest({ method, uri, accept }))).origin)
.to.deep.eq({ custom: api1.APIEdgeEndpoints["us-east-1"] });
};
await tester("GET", "/api/talks_v2", "application/vnd.vingle-v4+json");
await tester("GET", "/api/talks_v2/anything", "application/vnd.vingle-v4+json");
await tester("GET", "/api/cards/12345/likes", "application/vnd.vingle-v4+json");
});
- 67. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Unit Test는 필수
it("should send request to vingle-api-edge", async () => {
const tester = async (method: string, uri: string, accept: string) => {
const startTime = new Date();
expect((await handler(createRequest({ method, uri, accept }))).origin)
.to.deep.eq({ custom: api1.APIEdgeEndpoints["us-east-1"] });
expect(new Date().getTime() - startTime.getTime())
.to.be.lessThan(10, "it should not take longer than 10 ms");
};
await tester("GET", "/api/talks_v2", "application/vnd.vingle-v4+json");
- 68. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
Lambda@Edge, 이러면 고려해볼만 합니다.
- Application 앞에서 (CDN - Edge)할일이 있을때
- 트래픽을 동적으로 분배하고 싶을때
- CDN 레벨에서 캐쉬를 조작하고 싶을때
- Unit Test 는 필수
- CloudFront / Athena / Cloudwatch
- 자동화! 자동화!
- 69. © 2018, Amazon Web Services, Inc. or Its Affiliates. All rights reserved.
이런 문제를 함께 풀어가실 분을 기다립니다.
careers.vingle.net