본문 바로가기

프로젝트/WEB

Codemap 프로젝트 (소프트웨어 마에스트로 13기) - 아키텍처 구축

현재 소프트웨어 마에스트로에서 진행하고 있는 개발 프로젝트의 아키텍처에 대해 포스팅하려한다.

 

우리는 크게 세 가지 부분으로 나누었다.

 

1. Frontend

2. Main Server(BE)

3. Judge Server

 

프론트는 한 팀원이 Vue.js 프레임워크를 이용해 맡고 있고, 나는 메인 서버 개발 그리고 나머지 한 팀원은 채점서버를 구현하고 나와 같이 메인 서버 개발을 같이하고 있다.

 

아키텍처 구성


최종 아키텍처는 위와 같다.

 

앞으로 구성들을 하나하나 추가해보며 어떻게 전체 아키텍처가 구성되었는지 알아보자.

 

 

1. 메인서버


 

메인서버는 Spring Boot 프레임워크를 이용했다. MVC패턴을 사용하려고 했으나 한 팀원이 프론트를 전담하고 있기 때문에 굳이 View를 사용하지 않고 REST API 서버만 구현하면 돼서 View를 사용하지 않았다.

 

Spring 강의는 인프런에서 김영한님의 강의를 수강했다.

너무 많아서 아직 다 듣지는 않고 들으면서 개발했는데 다 듣기도 전에 개발이 끝나버렸다..(구글링 최고)

그래도 열심히 듣고있다.

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

위 강의는 무료 강의로 입문자들에게 Spring MVC ~ JPA까지 한번 쭉 훑어주는 강의인데 이해하기 좋다.

그리고 각 분야별로 자세한 강의는 커리큘럼을 따라 들으면 되는데 이것들은 유료이다.

나는 소마에서 인프런 강의비를 지원해줘서 그거로 듣고있다.

 

2. DB / API


DB는 MySQL을 사용했다. 

DB에서 내가 가장 자신있는 언어이기도 했고, NoSQL보단 RDBMS를 사용하는게 이해하기도 편하고 설계하기도 편했다. 

 

개발하면서 ERD 설계를 정말 많이 바꿨다. 하다보니 이것도 필요하고 저것도 필요하고 이래서.. 

다시한번 초기설계의 중요성을 느꼈다.

현재 ERD는 위와 같지만 더 개발하다보면 바뀔 가능성이 매우 다분하다.

근데 사실 테이블이 추가되든 컬럼이 추가되든 별로 두렵지는 않다. 왜냐면 JPA를 사용하기 때문이다.

Spring을 프레임워크로 채택하며 실제 프로젝트에 처음 적용해보았는데, 진짜 개사기다.

물론 MyBatis를 이용하면 직접 쿼리도 작성해볼 수 있는 기회가 있지만 너무 단순 반복 SQL작업이 많아 Data JPA를 사용했다.

 

또한 DB는 개발 중에는 메인 서버 로컬 디스크에 저장했지만, 현재는 AWS의 RDS를 사용하고 있다. 근데 너무 비싸서 내릴까 고민중이다 ㅠㅠ

 

 

3. WebSocket / JWT


백준이나 프로그래머스에서 코드를 제출하면 해당 코드에 대한 채점이 완료될 동안 '채점 중'이라든지 테스트케이스들에 대한 채점 현황을 알려준다든지로 어쨌든 내 제출이 어떤 상태인지를 알 수 있다.

 

우리도 이 기능이 필요했다.

 

근데 FE에서 루프를 돌려 계속 API를 호출하게 되면 상당한 Overhead가 발생할 것이다.

우리는 이를 해결하기 위해 웹소켓을 사용했다.

 

SockJS와 StompJS 라이브러리를 사용했고, FE에서 BE로 채점정보를 전달하면 BE는 채점 ID를 생성한 후, 해당 번호를 Unique ID로 가지는 연결을 생성한다. 그리고 BE는 만든 채점 ID를 FE에게 Return해주고 채점서버로 정보를 넘긴다.

이때 ID를 받은 FE는 해당 ID로 subscribe를 하여 BE가 지속해서 보내는 메시지를 응답받는다.

 

또한 로그인 기능에서 인증구현이 필요했다.

세션을 통한 인증을 할 수도 있지만, 유저가 많아졌을 때의 서버의 부담과 다중 서버로 운영될 시 세션정보 공유를 위한 추가적인 아키텍처 구성때문에 JWT 토큰방식을 사용했다.

 

이 역시 실제 프로젝트에 적용해본 것은 이번이 처음이었는데, 인프런의 JWT 강의를 이용했다.

이 강의는 무료다!

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-jwt/dashboard

 

[무료] Spring Boot JWT Tutorial - 인프런 | 강의

Spring Boot, Spring Security, JWT를 이용한 튜토리얼을 통해 인증과 인가에 대한 기초 지식을 쉽고 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

 

4. 채점서버


프로젝트의 특성 상 채점서버가 필요했고, 해당 채점서버에서 유저가 테스트한 코드를 실행해야 하는데 어떤 보안의 취약점이 있을지 몰라 독립적인 Sandbox 구축이 필요했다.

 

당연히 Sandbox 환경까지 직접 구현했다면 아주 좋았겠지만, 오픈소스를 이용하기로 했다.

https://github.com/ioi/isolate

 

GitHub - ioi/isolate: Sandbox for securely executing untrusted programs

Sandbox for securely executing untrusted programs. Contribute to ioi/isolate development by creating an account on GitHub.

github.com

국제올림피아드(IOI)에서 실제로 채점서버에 사용하는 샌드박스 구축을 위한 오픈소스이다.

IOI가 주관하는 모든 대회에서 이 기술을 사용하고 있기에 신뢰성이 있고, 매뉴얼 페이지가 나름 잘 구성되어 있어 사용하기 편했다.

http://www.ucw.cz/moe/isolate.1.html

 

ISOLATE(1)

isolate - Isolate a process using Linux Containers isolate options --init isolate options --run -- program arguments isolate options --cleanup Run program within a sandbox, so that it cannot communicate with the outside world and its resource consumption i

www.ucw.cz

 

사실 처음에 각자 Isolate를 이용해 각자 채점서버를 구현해보자고 해서 나는 C++를 사용해 구현해보았다.

근데 C++특성 상 아무리 깔끔하게 짜려고 해도 가독성이 너무 안좋아서 유지보수를 나밖에 할 수 없다는 점이 너무 큰 단점이었다.

그래서 한 팀원이 Java로 잘 모듈화 해서 짜보도록 기다려주고 만약 실패한다면 내가 짠 채점서버를 쓰려고 했다.

 

근데 약 2주뒤 채점서버 구현을 맡은 팀원이 너무 잘 구현해와서 그냥 그거 쓰기로 했다.

 

채점서버와 메인서버 사이에는 미들웨어가 하나 필요했다.

메시지 스트림 관리는 거의 모든 서비스에서 필수이고, 특히 채점과 같은 많은 트래픽이 요구되는 경우에는 더더욱 필요하다.

우리는 Rabbit MQ를 사용하기로 했다. 이또한 개발 단계에서는 채점 서버의 로컬 메모리를 활용했지만 현재는 AWS MQ를 사용하고 있다.

 

또한 메인서버와 채점서버는 AWS의 EC2를 사용하고 있다.

 

5. 저장소


플랫폼 서비스에 필요한 이미지 파일이나, 문제의 input, output 파일들은 용량이 매우크다. 따라서 별도의 저장소를 마련하는 것이 좋다는 생각을 했다.

 

내가 User인증을 구현하는 동안 한 팀원이 admin 페이지 작성을 했는데, 동시에 S3를 연동해왔다.

 

 

따라서 위와같은 아키텍처가 완성될 수 있었다.

 

다음 포스팅에서는 UI/UX 구축과 마무리 단계를 포스팅 할 것 같다.

 

커밍순!