JIGGAG

그림과 AWS로 인프라 알아보기

2020년 8월 23일

처음 개발을 시작했을때 화면도 그리고 서버도 구축하고 소위 풀스택을 경험할 수 있었다. 그리고 지금은 RN으로 프론트 개발을 하고 있다. 서버를 만지고 있는 다른 개발자분들을 보면서 괜히 이건 뭔가요 물어보고 싶고 사이드 프로젝트를 진행하다가 막히는 부분이 있으면 또 물어보고 싶은 마음이 가득하다. 프로젝트를 처음 시작할때 인프라 구조도를 그리고 이건 이렇게 저렇게 의견을 나눌때 우리 서비스가 이렇게 구성되는구나 하고 알아볼 수 있으면 좋겠는 마음도 있다. 그래서 최근에 인프라 관련 도서를 몇권 찾아보기 시작했다.

그림으로 공부하는 인프라 구조

전산실의 커다락 Lack 랙에 여러대의 서버가 조립되어있다. (사실 냉장고 같은 이 커다란 것을 랙이라고 부르는지 처음 알게 되었다.) 이 책에서는 그림으로 구조를 설명해주고 있어서 글로 기록을 남긴다는게 조금 어렵긴하지만 그래도 남겨본다. 서버는 웹, 애플리케이션, DB 서버로 구분할 수 있고 웹과 앱 서버는 내부 프로세스나 쓰레드를 여러개 돌려서 병렬처리가 가능하다. 이때 프로세스는 각각 독립적으로 실행되며 CPU 영향을 많이 받고 쓰레드는 하나의 프로세스 안에서 여러개를 동시에 실행시키는 것으로 외부 시스템자원보다는 프로세스 내부 자원의 영향을 받게 된다.

병렬처리

병렬처리를 과정에서 자원의 사용을 제어하고 데이터의 일관성을 유지하고자 베타적 제어를 사용하는데 이 제어가 걸려있으면 오히려 병렬처리가 되지 않는다. 예를들어 업데이트와 조회, 삭제 요청이 들어온 경우 이를 병렬처리했을때 데이터는 순차적으로 처리될 수 있게하려면 베타적 제어를 통해 업데이트를 하고 나서 조회, 삭제가 실행되도록 한다. (이것은 블로킹, 동기화 처리와 연관된 내용으로 보여진다.)

캐시

매번 서버에 동일한 데이터 조회를 요청하는 경우 요청이 들어올때마다 연산을 다시 해서 보내는 것보다 캐시해두었다가 캐시된 데이터를 반환해주는 방법이 있다. 클라이언트에서 요청이 들어왔을때 DNS를 거쳐서 캐시서버에서 해당 값을 찾아보고 없으면 서버로 요청을 보내고 캐시된 데이터가 있으면 캐시서버의 주소를 반환하여 처리하게 되므로 한 스텝을 빠르게 처리하는 장점이 있다. 그러나 이는 결국 원본 데이터와 캐시된 데이터 2곳에 저장해두어야하므로 자원을 소모하는 것이기에 모든것을 캐시한다고 좋은 것은 아니다. 매번 갱신되는 데이터거나 여러 데이터를 참조하고 있는 경우 캐시를 하더라도 데이터가 갱신되었기 때문에 새로 받아와야 하는 작업이 추가되어 오히려 캐시를 하지 않는게 자원낭비가 되지 않는 상황이다.

AWS 인프라 구축 가이드

서버를 운영하는 것은 환경을 구성하고 코드를 배포하고 서비스를 모니터링하는 것이다. 그렇다면 운영하는 서버의 모습은 어떻게 되어있을까. 하나의 서버에 DB와 애플리케이션 서버가 공존하는 경우 내부적으로 네트워크 설정이 없어도 된다. 또한 각각의 서버의 자원 사용량에 따라 서버를 증설하려고 할때 자원이 비효율적으로 이용될 수 있는 단점이 있다. 앱 서버와 DB 서버를 분리하여 사용하는 경우 서버와 서버 사이에 요청이 오고가면서 지연시간이 발생할 수 있고 네트워크 보안 설정이 중요하게 된다.

여러대의 서버가 존재하는 경우 클라이언트의 요청을 분산처리하여 하나의 서버에 요청이 몰리지 않도록 해주는 ELB가 있다. 여러 서버에 분산처리를 위해 ELB는 각각의 서버가 정상적으로 작동하고 있는 상태인지를 확인하는 health check를 계속 요청하게 되고 이를 이용해 서버 장애관리가 가능하도록 한다.

서버의 자원 사용량에 따라 증설을 위해 로드밸런서를 앞에 붙여서 서버의 CPU 사용량 또는 특정 시간대 설정 등으로 인스턴스를 증가, 감소를 자동적으로 해주는 Auto Scailing이 가능하도록 한다. 이때 서버를 통쨰로 늘리는 방법과 서버안에 앱 서버만 로드밸런서를 추가적으로 구성하여 앱서버를 증설하는 방법이 있다.

HTTPS, SSL/TLS

인증된 기관으로부터 발급받은 인증서를 설치하여 암호화된 통신을 할 수 있게 된다. 사용자가 HTTPS로 클라이언트에 요청하면 DNS에서 SSL/TLS 암호화 통신을 서버에 요청한다. 서버는 공개키와 설치된 인증서를 반환하고 클라이언트에서 인증서를 확인 후 공개키로 사용자의 요청을 암호화해서 다시 서버에 전달하면 서버는 복호화하여 요청을 받고 응답값을 다시 암호화하여 클라이언트에 전달하게 된다.

배포

무중단 배포의 방법으로는 현재 위치 배포, 서버 단위의 블루/그린 배포, 서버 내부 블루/그린 배포를 설명하고 있다.

현재 위치 배포는 로드밸런서에 이용중인 인스턴스의 절반을 연결 해제 후 해제된 인스턴스에 배포를 한 뒤 다시 연결을 하는 방법이다. 인스턴수 수가 절반이 되면서 서비스 과부하가 걸릴 수 있는 단점이 있다. 서버 단위의 배포는 현재 위치 배포와 동일한 방법이나 배포된 그룹을 모니터링 하다가 상황에 따라 구버전 또는 신버전을 삭제하는 방법이다. 현재 위치 배포와 서버 단위의 배포는 구버전과 신버전이 동시에 운영될 수 있는 수준의 업데이트인 경우에만 사용이 가능하다.

서버 내부적으로 블루/그린을 나눠서 배포하는 방법은 단일 인스턴스를 이용중이여서 연결을 해제 후 배포 할 수 없는 경우에 현재 사용중인 애플리케이션 서버의 포트가 아닌 다른 포트로 추가 배포 후 연결되어 있는 포트를 변경하는 방법이다. 이때 이미 연결이 되어있는 요청에 대해서는 중간이 끊기지 않고 들어온 데이터 까지는 동작하고 새로 들어오는 요청부터 신버전으로 전송될 수 있도록 해야한다. 단순하게 웹서버를 restart하는것이 아니라 reload를 하므로써 이미 연결된 요청은 정상 동작하도록 해준다.

결론

인프라를 구성한다는 것은 자원이 효율적으로 이용될 수 있도록 구성하는것 같다. 커다랗게 뚠뚠 구성할 수 있으나 그럼 비용이 가장 비효율적이게 될 것이다.

현재 프로젝트를 진행하다보면 내가 직접 인프라를 구성하는 일은 없다. 다만 우리가 사용하고 있는 서버의 구조를 알아두고 에러가 발생했을때 어느쪽을 확인해줬으면 좋겠다라고 또는 원인이 되는 부분을 설명해주었을때 같이 공유하고 의견을 나눌 수 있고 싶다. (사실 깊게 알아가는게 아니라서 오히려 겉핥기가 되어 이도저도 오히려 독이 되는건 아닐까 걱정이 된다... 더 찾아보면 되지)