Curriculum/Wanted Free Onboarding Backend

[10~14일차] 3번째 기업과제 AWS EC2, Docker 배포 담당하기

작은코딩 2022. 7. 17. 03:46

[프리 온보딩 일기]

3번째 기업과제가 시작되었다. 

 

게임 회사에서 내준 기업과제인데 이번에는 배포를 담당하게 되었다. 

 

여기서는 서비스 아키텍처를 구성한 이유와 발생한 이슈들에 대해 간단히 기록하고 자세한 배포 과정과 트러블 슈팅은 다른 카테고리에서 기록해야겠다.


🎨 서비스 아키텍처 

피그마로 작성한 아키텍처!

배포에 사용한 기술

  1. AWS EC2 리눅스
  2. Docker
  3. Nginx
  4. uWSGI
  5. Django(DRF)
  6. Mysql
  7. redis

아키텍처 설명

배포 서버는 프리티어로 사용 가능한 AWS EC2의 우분투 t2 서버를 사용했다.
그리고 Docker compose를 이용해 4개의 컨테이너를 띄우고 각각 컨테이너 포트를 연결했다. 

 

먼저 클라이언트가 request 요청을 보내면 web server인 nginx에서 받아 service로 데이터를 넘겨준다.
이 데이터는 uwsgi를 통해 웹 애플리케이션인 장고로 들어가게 된다.

Django에서는 각각의 서비스 로직을 통해 DB인 mysql에서 데이터를 조회하거나 저장하는 등의 작업을 수행하고 서버 메모리에 캐싱된 데이터를 이용하기 위해 redis를 이용한다.

 


❓❔ 각 기술과 아키텍처 구성 이유

아키텍처

아키텍처는 두 가지 경우를 생각했다. 

  1. AWS EC2(docker - nginx, uwsgi, django, mysql, redis)
  2. AWS EC2(docker - nginx, uwsgi, django), AWS RDS(mysql),  AWS Redis

프로젝트의 규모를 떠나 하나의 서버에 모든 서비스를 담는 구조는 좋지 않다고 생각한다.
너무 한 서버에 의존하게 되면 서버가 다운될때 모든 서비스가 정지하는 큰 위험이 있기 때문에
2번 방법이 좋은 방법이라고 생각되는데, AWS의 기능을 많이 사용하게 되면 비용이 많아지는 이유로 이번 프로젝트는 1번 방식으로 결정을 내렸다.

 

기술

  • Why Docker
    • docker-compose를 활용해 원하는 아키텍처를 빠르게 구성할 수 있다.
    • 서비스가 host에서 동작하는게 아닌 container에서 동작하기 때문에 의존성과 같은 문제가 생길 가능성이 적다.
  • Why Nginx
    • 로드밸런싱을 활용해 트래픽을 분산 할 수 있다.
    • SSL 기능을 사용해 데이터를 안전하게 전달할 수 있다. 
    • reverse proxy 기능으로 client에서 서버에 직접적으로 접근하는 것을 막아준다.
    • 콘텐츠를 캐싱하여 동일한 요청에 대해 더 빠른 속도로 처리할 수 있게 해 준다.
  • Why uWSGI
    • 기본 적으로 Django에서 제공하는 runserver는 개발 환경을 위한 경량화된 웹 서버이기 때문에
      보안 감사나 성능 테스트를 거치지 않았다.
      그렇기 때문에 장고 공식문서에서도 프로덕션 환경에서 runserver를 사용하지 말라고 한다.
    • wsgi 프로그램은 대표적으로 gunicorn과 uwsgi가 존재하는데 대량의 리퀘스트를 처리할 때
      성능과 안정성이 모두 향상된다.(참고)
    • gunicorn을 써도 되지만 이번엔 uwsgi를 사용
    • nginx와 호환성이 좋다는데 이 부분은 확인해보지 못했다.
  • Why DRF
    • RESTful한 개발을 하기 위해 django rest framework를 이용해 개발했다.
    • 로그인, 회원가입, 인증, CORS, data parsing 등 반복적으로 구현해야 하는 부분은
      라이브러리를 통해 간단하게 사용이 가능하다.
  • Why Mysql
    • 빠르고 안정적이며 사용하기 쉽고 인기가 많기 때문에 앞으로 다루게 될 가능성이 가장 많다고 생각했다.
    • mysql은 오픈 소스 라이센스를 따르기 때문에 무료로 사용할 수 있고,
      다양한 운영체제에서 사용할 수 있으며, 여러가지 프로그래밍 언어를 지원한다.
  • Why Redis
    • 클라이언트에서 정보를 조회하는 서비스 로직을 만들 때 무조건 DB를 경유하게 설계하면 부하가 많이 걸린다.
       따라서 자주 변하지 않는 데이터는 메모리에 캐싱하기 위해 redis를 사용했다.

⛔ 트러블 슈팅

배포를 마치고 git hub에 푸시된 내용으로 업데이트를 하는데 난데없는 에러를 만났다.

배포 설정은 변한 게 없는데 uwsgi 플러그인을 찾을 수 없는 에러가 발생했는데, 여러 방법으로 시도해도 해결되지 않았지만 밤새 매달린 끝에 마지막 시도라고 생각한 방법이 적중해서 에러를 해결할 수 있었다.

 

구글링으로 검색된 여러 방법을 시도하면서 서버 설정이 꼬여 EC2 인스턴스를 3개 바꿔가며 시도했는데

해결하고 나니 방법은 정말 간단했다.

 

에러가 발생한 정확한 이유는 진단할 수 없었지만 짐작가는 이유는 새로운 패키지가 설치되며 도커 이미지를 새로 빌드할 때 uwsgi 버전이 달라진 게 이유 같다.

중요 로그 기록은 팀 노션에 남겨놨었는데 uwsgi 버전이 2.0.19.1에서 2.0.20으로 바뀐 걸 확인할 수 있었다.

하지만 버전을 다시 2.0.19.1로 바꿨는데 이슈가 해결되지는 않았다.

 

밤새면서 여러가지 방법을 시도했기에 모든 과정을 여기에 남기기는 부적절하다 생각되어 다른 카테고리에 따로 정리하도록 하고 여기서는 에러 내역과 해결 방법만 간단히 남겨보자.

 

Error

해결 코드

# uwsgi.ini
[uwsgi]
base=/app/
workdir=%(base)
chdir=%(base)
plugins=/usr/lib/uwsgi/plugins/python3
http-socket=:8000
;socket=:8000
module=config.wsgi
callable=application
master=true
processes=1
threads=1
pidfile=/app/server.pid

 

에러를 해결하기 위해 구글링을 했을 때 대부분의 방법은 plugins-dir로 경로를 명시해주었다.

그래서 plugins-dir에 실제 플러그인이 있는 경로 등 다양한 경로를 시도했는데, 내 케이스는 plugins에 직접 경로를 명시했더니 해결되었다.

 

로그를 확인해봐도 plugins-dir을 지정했지만 work 디렉토리에서 파일을 찾는걸로 확인되는데, 알고 보면 너무 쉽게 해결이 돼서 허탈하지만 그래도 해결했으니까 :)

 

[과제 레포지토리]

https://github.com/pre-onboarding-3rd-team-H/03_GameDuo_TeamH

 

GitHub - pre-onboarding-3rd-team-H/03_GameDuo_TeamH: 게임듀오 기업과제 레포지토리입니다. 게임의 구조를 알

게임듀오 기업과제 레포지토리입니다. 게임의 구조를 알아보는 프로젝트로 기본적인 로그인 로그아웃 기능 및 레이드의 상태조회, 랭킹조회 기능을 구현하여 특정 게임공간을 여러명의 유저들

github.com

 

[과제 노션]

https://wool-cobalt-585.notion.site/8940341de3ca468898d177ad08b683aa

 

게임듀오 과제페이지

📝 업무 분배

wool-cobalt-585.notion.site