AWS

각 서비스에 맞는 아키텍처는 무엇일까? - 시간을 알려주는 웹앱의 아키텍처를 개선하면서 설계해보자

S_N_Y 2024. 3. 30. 11:33

세 가지의 웹앱 서비스를 예시로 아키텍처 설계 시리즈를 적으려고 한다.

설계에 관심이 있으면 서비스 종류가 무엇이 있는지 먼저 조금 파악을 한 뒤에 이 글을 읽으면 좋을 것이다!

 

#0 들어가기 앞서

여러 가지 서비스들을 정리해봤는데 이것들이 실제로 어떻게 연결되고 관리되는지도 조금 다뤄보는게 좋을 것 같아 올려본다..! 아키텍처에 관한 부분은 꼭 정답이라고 할 수는 없지만 여러 가지 사례를 통해 어떤 서비스들이 어떤 식으로 동작하는지에 대해 정리해본다면 많은 분들께도 도움이 될 것 같아 정리해보려고 한다.

+) ⚠️ 가장 기초적인 아키텍처 설계 예시이기 때문에 확장성을 고려해서 초반부터 서버리스 세팅을 할 수 있지만 일단 기초 자료로써 이 글을 다루려고 하니 실제 아키텍처 설계와 똑같이는 할 수 없다는 것을 먼저 언급하고 시작하겠다!

 

#1 사례 1️⃣) 사람들에게 시간을 알려주는 웹앱

<조건>

- 너무 단순하기 때문에 DB가 필요없다. (각각의 인스턴스와 서버는 시간이 몇 시인지 알고 있다.)

- downtime(다운타임)을 수용할 수도 있지만 앱이 인기가 많아질 때의 확장성을 대비하여 다운타임을 제거할 수 있도록 수직/수평적 확장할 필요도 있어보인다.

 

✳️ 초기

1) ✴️ 극초기 - 심플하게 시작할 때

t2.micro 인스턴스와 사용자가 있다고 치자.

사용자가 시간을 물어보면 오후 5:30이라고 답하는 애플리케이션이다.

공용 EC2 인스턴스가 있고 무슨 일이 생기면 재시작할 수 있도록 EC2 인스턴스가 고정 IP주소를 갖도록 하고 싶을 것이다.그렇기에 Elastic IP주소를 연결할 것이다.

 

2) ✴️초기 1 - 사용자가 조금 늘어났을 때

애플리케이션이 점점 더 많은 트래픽을 갖게 되면서 t2.micro 인스턴스로는 충분하지 않다는 것을 깨닫게 되고 부하를 처리하기 위해 t2.micro 인스턴스를 조금 더 큰 m5.large로 교체(수직확장)하는데 이 경우에는 인스턴스를 중지시키고 인스턴스 유형을 바꾼 다음에 그 후에 인스턴스를 다시 시작해야 한다는 특징이 있다.

동elastic IP를 가지고 있기 때문에 동일한 Public IP를 가지게 되고 사람들은 여전히 애플리케이션에 접근할 수 있다.

=> 그런데.. 이런 식으로 바꾸면 위에서도 잠깐 언급했듯이 M5으로 업그레이드할 동안 downtime이 발생할 수밖에 없고 그동안 애플리케이션에 접근할 수 없으니 그리 좋은 방법은 아니다.👎

 

3) ✴️ 초기 2 - 사용자가 조금 더 늘어났을 때

사람이 조금 더 늘어나서 수평적인 확장을 할 때인데 하나의 M5 인스턴스는 하나의 Elastic IP를 가질 수밖에 없기 때문에 사용자는 인스턴스들과 통신하려면 이 세 개의 elastic IP의 정확한 값을 알고 있어야 한다..

=> 사용자들은 서비스가 커질 때마다 점점 더 많은 IP를 알아야 하고 개발자들은 더 많은 인프라를 직접 관리해야 한다는 큰 단점이 있다🥵👎

 

4) ✴️ 초기 3 - 초기2보다 더 괜찮게 해보기 (개선사항 적용)

그러면 접근 방식을 조금 다르게 바꿔서 M5유형의 EC2 인스턴스 세 개가 여전히 있는데 관리하기 어려운 elastic IP를 제거한다. 그리고 또한 한 계정에서 region마다 겨우 다섯 개의 elastic IP만을 가질 수 있다는 단점을 커버할 Route 53을 설정하면 된다.

웹사이트 URL은 api.whatisthetime.com이고 TTL이 한 시간인 A레코드로 정했다고 치자.

(A 레코드로 정했다는 건 DNS로부터 IP리스트를 받는다는 의미 - Route53의 A레코드는 IP라는 것을 기억하기)

이제 사용자들이 Route53을 쿼리하는데 그러면 EC2 인스턴스들의 IP주소를 얻게 되고 이는 시간에 따라 변하고 Route53이 업데이트되고 동기화를 유지할 거라 전혀 문제가 되지 않는 부분이다. 사용자들은 이제 EC2 인스턴스에 접근할 수 있고 관리한 elastic IP도 더 이상 존재하지 않는다.

=> 즉, Route53을 사용해서 개선되었다! 

...

그런데 이번에는 상황에 따라 곧 바로 인스턴스를 추가/삭제할 수 있도록 확장하고 싶어지는데?🤔

인스턴스를 제거하면 어떻게 할까?

이대로라면 가장 윗쪽에 있는 사용자들이 해당하는 M5 인스턴스와 통신 중이었는데 없어져버린다면..? TTL이 1시간이었기 때문에 Route53쿼리를 시조하면 동일한 응답을 1시간 동안 사용하게 되긴 하지만 그 인스턴스는 더 이상 존재하지 않은 상태가 되어버린다. 아마 1시간 뒤에는 아래의 두 인스턴스에는 접속할 수 있어서 다시 즐길 수는 있지만 지금 당장은 최악이다.🥶

=> 결국 이것조차 한계점이 명확한 아키텍처 설계이다.👎

 

✳️ 중반

5) ✴️ 중반 - 초기3보다 더 괜찮게 해보기 (추가 개선사항 적용)

로드 밸런서를 추가해보는 것이다.

이제 더 이상 Public 인스턴스는 없고 Privatee EC2 인스턴스들이 있는데 이 모두를 같은 AZ에서 실핼할 것이다.

로드 밸런서는 'health check(상태 확인)' 기능이 있는데 한 인스턴스가 다운되거나 작동하지 않으면 사용자로부터 해당 인스턴스로 트래픽을 전송하지 않게끔 한다..! ELB와 EC2를 먼저 연결시켜보면 ELB는 공개되겠지만 private은 뒤에 숨어있는 구조가 된다.

그리고 이 security group 규칙을 사용해서 이 둘 사이의 트래픽을 제한할 수도 있으니 꽤 괜찮아진다.

이제 whatisthetime.com에 대해 사용자들이 쿼리하지만 로드 밸런서가 IP주소를 지속적으로 바꾸기 때문에 이번에는 A 레코드가 될 수 없고 대신 로드 밸런서이기 때문에 Alias(별칭)레코드를 사용할 수 있다.

Alias(별칭)레코드는 완벽한게 Route53으로부터 ELB를 가리킬 것이고 모든게 엄청 잘 작동할 것이기 때문이다. 여기서 DNS를 바꾸지만 사용자들은 이제 로드 밸런서에 접속한다. 그리고 로드 밸런서는 EC2 인스턴스로 리디렉션하고 트래픽의 균형을 잡는다.

=> 이제 로드 밸런서로 이 인스턴스들을 추가/삭제하고 정렬할 수 있기에 너무 좋고 또한 health check가 가능하기 때문에 사용자들에게 downtime도 없다😀👍👍

...

그러나 수동으로 인스턴스를 추가하고 제거하는게 여전히 어려운데

이걸 자동으로 추가/제거하는 방법은 없을까?🤷‍♂️

=> 오토 스케일링 그룹 실행하면 된다. ⬇️⬇️

 

✳️ 후반

6) ✴️후반 - 중반보다 더 좋게 하기 (추가 개선사항 적용)

오토 스케일링 그룹을 통해 EC2 인스턴스들을 관리하게 되면 오토 스케일링 그룹의 요청에 따라 확장하도록 설계된다.  애플리케이션에 downtime도 없고 오토스케일링과 로드 밸런싱이 있어서 더더욱 좋은 설계가 완성된다.

...

여기에 더 나아가 지진같이 예기치 못한 재해가 발생해서 AZ 1이 다운된다면..?🌩️

그렇게 돼서 애플리케이션이 완전히 다운된다면 굉장히 큰 손해이다.

그렇기에 Amazon에서 아마 이렇게 설계를 했다면 다중AZ 사용을 추천한다고 뜰 것이다.

그래서 여기서 더 나은 개선사항을 적용해보는 것이다.

 

➕) 추가 개선사항 : 다중 AZ 적용하기

이번에도 ELB를 통해 할 수 있는게 있는데 health check 뿐만 아니라 다중 AZ도 추가될 것이다.

AZ1~3이 실행될 거고 이 ELB는 세 개의 AZ가 있는 상태이며 오토 스케일링 그룹 역시 다중 AZ에 걸쳐있게 된다.

=> 이렇게 하면 하나의 AZ가 다운이 되더라도 다른 AZ가 있기 때문에 사용자를 위한 트래픽을 처리할 수 있다는 장점이 있다.

 

) 추추가 개선사항 : 용량 예약하기

기본적으로 애플리케이션의 비용을 줄이는 작업을 시작하는 것이다.

왜냐면 1년 내내 두 개의 인스턴스가 항상 실행 중일 것이기 때문이다.

=> 그러니까 오토 스케일링 그룹의 용량을 최소화하기 위해서 인스턴스를 '예약' 함으로써 비용 절감도 더 잘 될 수 있다.

 

(여기에 더 추가로 극단적으로 비용을 절감이 필요할 때, 일시적인 요청이 필요한 것은 스팟 인스턴스로 전환해서 사용할 수도 있다..! -> 근데 알다시피 스팟 인스턴스는 용량이 넘치면 인스턴스들을 종료시키게 할 수 있기 때문에 신중해야 한다⚠️)