본문 바로가기

Issue

소셜 네트워크 앱 개발 프로젝트 아키텍처 고민 및 해결 과정

업체(이하 클라이언트)를 통해 특정 컨셉을 지닌 소셜 네트워크 및 메신저 어플리케이션의 외주를 진행하게 되었다.
이후 최종적으로 계획하고 있는 프로젝트의 규모가 작지 않기도했고, 일정이 타이트하게 구성되는 등의 문제로
나와 지인 한 분이 백엔드 및 인프라 구축을 맡게되었고, 지인을 통해 소개받은 플러터 개발자 분께서 앱개발을 맡아 진행하기로 하였다.

 

정확한 컨셉을 공개할 순 없지만, 몇몇의 주요한 기능들을 중심으로 어떻게 아키텍처를 설계했는지 이야기해보도록 하겠다.

  • 사진, 동영상의 멀티미디어를 통한 실시간 채팅 (메신저)
  • 소셜 네트워크 서비스
  • 특정 사진, 동영상(멀티미디어)의 AI분석 (추후 개발)
  • TTS 관련 서비스 (개인 사용자 목소리 기반)
  • SNS 간편 로그인(OAuth 2.0)
  • 알림 기능

 

모놀리식 vs 마이크로서비스 아키텍처(MSA) 선택의 고민

프로젝트 초기에 가장 큰 고민거리 중 하나는 모놀리식 아키텍처마이크로서비스 아키텍처 중 어떤 것을 선택할 것인가였다.

모놀리식 아키텍처를 통해 타이트한 개발 및 배포를 비교적 쉽게 일정에 맞추고, 통합 테스트를 용이하게 하여 지속적으로 실시간 피드백을 받으며 클라이언트와 커뮤니케이션이 쉽게 이뤄질 수 있었지만, 시스템이 복잡해지고 트래픽이 증가할수록 확장성과 유지보수성이 떨어진다는 단점을 지니고 있었다.

 

반면 마이크로서비스 아키텍처는 서비스 별로 독립적인 개발과 배포가 가능하고 확장성과 회복성이 뛰어나다는 장점이 있지만, 분산 시스템 특유의 복잡성과 서비스 간 통신 오버헤드가 발생할 수 있기에 서비스 간 정확한 역할 구분 및 통신 방법에 대한 정의 및 관리가 필요했다.

 

클라이언트와의 여러번의 회의를 통해 전달받은 서비스의 개요도를 통해 초기 개발 부분과 이후 확장되는 서비스 영역이 나눠져 있다는 것을 알게 되었고, 다양한 기능이 더 추가될 수 있다는 것으로 예상되어, 트래픽 증가 및 유지보수에 유연하게 대응해야 했기 때문에 마이크로서비스 아키텍처를 적용하기로 결정했다. 다만 초기에는 마이크로서비스로 완전히 전환하기보다는 프로젝트의 지속적인 피드백을 수행하며 점진적으로 모놀리식 아키텍처에서 마이크로서비스로 전환해 나가는 전략을 세웠다.

 

클라우드 서비스 제공자 선택의 고민

마이크로서비스 아키텍처를 선택함에 따라 클라우드 서비스 제공자를 선택하는 것도 중요한 이슈였다. AWS, Azure 등 다양한 클라우드 서비스들의 장단점을 분석하였고, 특정 클라우드 서비스를 선택하더라도 자체 Docker, Kubernetes 등의 개발을 통해 진행할 것인가,
AWS가 제공하는 다양한 관련 서비스를 사용할 것인가 분석하여 고민하였다.

먼저 멀티미디어 정보를 통해 사용자의 보안성에 대한 우려가 있었기 때문에, 보안그룹에 대한 엄격한 설정이 필요했고, EC2, EKS 등 컨테이너 기반 서비스를 Docker와 동일하게 사용할 수 있다는 점과, Lambda, API Gateway 등 서버리스 서비스를 활용하여 조금 더 효율적인 형태의 마이크로서비스 아키텍처를 구현할 수 있다는 점에 AWS의 제공되는 서비스를 통한 인프라 구축을 진행하기로 하였다.

 

채팅 서비스 구현 방식 및 프로그래밍 언어의 고민

실시간 채팅 기능은 사용자 경험을 좌우하는 중요한 기능이었기 때문에, 채팅 서비스 구현 방식에 대한 고민도 깊었다.

먼저 실시간 메세징을 위해 WebSocket과 Socket.IO 중 어떤 기술을 사용할 것인지 검토하였고, Socket.IO가 제공하는 룸, 네임스페이스 등의 기능과 폴링 기반 폴백을 제공한다는 점에서 Socket.IO를 채택하였다.

 

채팅 서버 구현 언어로는 Node.js와 Spring 중에 고민하였고 또한 프로젝트의 전체 기반 백엔드 서버의 구현 언어에도 영향을 줄 수 있는 고민이었다. 먼저 프로젝트 서비스의 전반적인 기반은 Spring으로 작성하기로 하였다. 프로젝트 특성상 안정성과 이후 유지보수 혹은 확장성에 유리한 측면이 존재하기 때문이다. 하지만, Node.js가 이벤트 기반 비동기 I/O를 지원하여 실시간 메세징 구현에 조금 더 적합하며, 빠른 개발이 가능하기 때문에 실시간 메세징에 대한 부분만 Node.js가 처리하도록 하였고, 채팅 데이터의 영구 저장 및 관리 등 다양한 동작은 Node.js에서 Spring의 특정 API를 개발해 두어 비동기적인 통신으로 수행하도록 하는 등의 계획을 구성하였다.

이렇게 하여 Spring기반의 백엔드 서버를 별도의 EC2로 작성하고, Node.js와 Socket.IO를 통해 실시간 메세징을 담당하는 서버를 별도의 EC2로 구성하는 MSA 형태의 개발을 진행하도록 계획하였다.

 

서비스 간 통신 및 데이터의 정합성 확보 방안

마이크로서비스 아키텍처에서는 서비스 간의 통신 방식과 데이터 정합성 확보가 중요한 이슈이다. 이 상황에서 동기식 통신과 비동기식 통신의 장단점을 분석하고, 대부분의 서비스 간 통신은 RESTful API를 통한 동기식 통신을 사용하되, 메시징 서버와 Spring의 통신은 메세지 큐를 활용한 비동기 통신을 적절히 활용하는 것이 좋지 않을까 하고 생각하였다.

 

 

AWS의 부가적인 서비스 선택에 대한 고민

AWS를 선택한 이유에는 EC2, EKS와 같은 Docker와 비슷한 컨테이너 기반의 프로젝트 설계가 가능하다는 점 뿐만이 아니었다.
RDS, Lambda, S3 등 여러가지의 서비스에 대해 제공해 주고, API Gateway의 사용과 VPC를 통한 보안성을 높인 통신이 가능하다는
것이 선택에서의 큰 이유를 차지하였는데, 이를 기반으로 프로젝트의 설계를 어떻게 구성하게 되었는지 설명하겠다.

먼저 기존의 메세징 서버인 Node.js 서버와 프로젝트의 기반이 되는 Spring 서버는 각각 EC2를 사용하여 컨테이너 기반으로 관리하게 될 예정이다. 또한 Node.js는 동시성 등의 문제로 인하여 DB의 직접적인 접속이 불가능하게 하고, Spring을 통해서만 접속 가능하도록 Spring과 VPC를 이용해 보안그룹 설정을 진행할 예정이다.

또한 DB는 RDS라는 서비스를 통해 구축하여 마찬가지로 VPC를 기반으로 Spring의 EC2와 그룹을 구성하고, 인증 정보를 관리하기 위한 JWT 토큰을 관리하기 위해 Redis를 사용할 예정인데, AWS ElastiCache를 사용할 예정이다. 이후 주고받는 멀티미디어에 대한 정보를 저장하기 위해서 별도의 저장소를 활용할 예정인데 그로 적합한 것이 AWS S3 서비스이다.

마지막으로, 멀티미디어의 AI 분석과 TTS등의 서비스를 활용하게 될 예정인데, TTS는 추후 프로젝트의 계획에 따라 달라질 수 있지만, 
AWS Polly를 사용할 수 있을 것 같다. 멀티미디어의 AI 분석을 사용하게 되는 부분이 있는데 초기에는 Python의 OpenCV를 통해 단순한 선명도를 기반으로 아마 구현하게 되었고, 추후 클라이언트 쪽에서의 자체적인 개발을 통해 AI 분석 멀티미디어 분석 처리가 들어가게 될 예정이었고 현재 단순 OpenCV 기반의 멀티미디어 분석은 별도의 EC2 서버까지 구성해 두기에는 오버헤드가 발생할 것 같아, AWS Lambda를 이용해 서버리스로 구현해 두고, 추후 개발이 완료되면 Flask의 EC2로 RESTful API형태로 통신을 진행하면 될 것 같았다.

 

 

구현된 내용에 대한 간략한 구상도

프로젝트 개발의 리스트를 줄이기 위해 간략하게 구성된 내용이고 반복적인 피드백과 프로젝트 계획을 진행하며 변경될 수 있는 내용이다.

 

 

서비스 간 통신 방법에 대한 명확한 규정은 프로젝트의 진행을 통해 구체적으로 계획하게되며, 수정하게 될 것이고 아마 다음 계획 단계에서 CI/CD 구축, 모니터링 등 개발 및 운영 단계에서의 고민들을 수행하게 되며 해결하게 될 것 같다.
또한, 기존에 계획해두고 구축해 두었던 정보들도 충분히 요구사항에 맞춰 변경될 가능성이 존재하므로 조금 더 유연한 설계와 사고가 필요할 것 같다.

마치며

얼마전, 아키텍처 설계는 프로젝트의 성패를 좌우하는 매우 중요한 단계라는 점을 느끼게 되었다. 어쩌면 계속 느껴왔지만 귀찮다는 이유로 대충대충 넘어가자는 느낌으로 크게 고려하지 않고 넘겼을 수 있다. 이런 행위는 어떤 형태로든 큰 독이 되어 찾아왔고 이번 기회에 이것을 바로 잡자는 생각으로 이번 프로젝트의 초기 설계 단계에서의 결정을 신중하게 접근하였다. 이번 프로젝트에서는 모놀리식과 마이크로서비스, 클라우드 서비스 제공자, 사용 기술 스택 선택 등 다양한 옵션들의 장단점을 면밀히 분석하고, 프로젝트의 특성과 요구사항에 맞는 최적의 아키텍처를 설계하는 것을 중점적으로 생각해본 것 같다.

 

또한, 아키텍처 설계 과정에서는 다양한 이해관계자들과의 소통과 협업이 필수적이라는 점을 깨달았습니다. 개발팀 내부뿐만 아니라 클라이언트(비즈니스 팀, 디자인 팀, 운영 팀) 등 다양한 이해관계자들의 요구사항을 수렴하고, 기술적 제약 사항과 비용, 일정 등을 고려하여 최적의 솔루션을 도출해야 한다. 이를 위해 효과적인 커뮤니케이션 스킬과 문제 해결 능력, 그리고 다양한 도메인에 대한 지식 및 이해가 필요하다는 것을 느꼈다.

 

이번 프로젝트에 초기 단계를 신중하게 계획하며 최신 클라우드 기술과 마이크로서비스 아키텍처, 그리고 확장 가능성이 존재하는 규모 있는 시스템 설계에 대한 경험을 쌓을 수 있던 것 같다. AWS의 다양한 서비스를 활용하여 확장가능하고 안정적인 시스템을 구축하는 방법을 배웠고, 마이크로서비스 간의 통신과 데이터 정합성을 확보하기 위한 고려사항들에 대해 고민해 볼 수 있게 되었다.

 

론 이후에 여러 요구사항과 문제 해결을 진행해나가며 프로젝트의 계획 단계는 수정될 수 있지만, 반복적인 계획 > 피드백 > 수정의 과정을 효율적으로 수행하는 것이 프로젝트의 성공을 위한 지름길이라고 생각되며, 각각의 단계는 매우 신중하고 유연하게 설계되어야 한다는 것을 느끼게 되었다. 무엇보다 이해관계자들과의 요구사항에 대한 문제를 해결해 나가는 과정을 통해 커뮤니케이션 스킬 및 문제 해결 능력과 새로운 기술을 학습하고 적용할 수 있는 능력이 개발자로서 중요한 역량이라 할 수 있지 않을까 생각하게 되었다.