꼬꼬마 개발자 3명의 MSA여행기

4 minute read

2020년 겨울 좋은 기회를 얻어 뉴로어소시에이츠라는 기업에서 인턴으로 근무했었다.

당시 회사는 e-commerce 관련 새로운 프로젝트를 준비하고 있었고, 나는 그 프로젝트의 초기 버전 앱 제작에 투입되었다.

새롭게 시작되는 프로젝트이니만큼 아무것도 없었고, 밑바닥부터 쌓아올려야 했었다. 심지어 MSA의 형태로 서비스가 구성되어야 했는데 나와 팀원들은 MSA의 M자도 모르는 상황이었다. 약 2달이라는 기간동안 정말 많은 고민과 시행착오들을 격으면서 최종적으로 우리들만의 MSA를 완성하게 되었다.물론 지금와서 보면 정확한 MSA라고 말할 수는없고, (SOA에 더 가깝…) 완성된 MSA또한 부족한 부분이 많다.

하지만 조금씩 개선되어갔던 구조안에 정말 수많은 고민들이 녹아있고, 점점 구색을 갖춰가는 모습을 보며 정말 큰 보람과 재미를 느꼈다. 또한 이렇게 어떤 서비스의 밑바닥부터 쌓아올려볼 경험은 당분간 다시 해보기는 힘들것 같은 정말 그 어떤 것보다 값진 경험이었다.

따라서 그 값진 경험들을 기록해 두고 싶고, 공유해보려고한다.

참고 : 다시한번 밑밥을 깔자면 최종적으로 나온 결과물도 엄밀하게 MSA의 형태라고 말할 수는 없고, 실제 상용화되기에는 턱없이 부족한 수준이다. 그러니 그냥 나와 팀원들의 고민과 이를 어떻게 해결했는지에 조금 더 초점을 맞춰 읽어주면 감사하겠습니다. 또한 이 글에 나오는 용어들은 흔히 MSA에서 쓰이는 용어들과 다를 수 있습니다.

참고2 : 해당 프로젝트가 기업의 프로젝트였기 때문에 서비스의 자세한 기능들이나 속성들을 노출할 수 없었습니다. 양해바랍니다.

먼저 최종 결과물을 보고 전체적인 구조에 대해 알고 가자.

msa-final

우선 크게 A, B, C 이렇게 세개의 서비스로 나누어져 있다. B와 C 서비스는 데이터베이스하고만 관련이 있는 서비스였고 크게 복잡하지 않았다.

반면 A서비스는 실시간으로 Crawling Job을 수행해야했고, 그 대상이 n개로 늘어날 수 있는 scalability를 지닌 형태여야했다. (A_sub3 ~ A_sub n, A_CrawlJob3 ~ A_CrawlJob n)

따라서 앞단에 Service A가 하나의 요청에 대해 뒷쪽으로 n개 서비스들에게 비동기적으로 요청을 보냈고 결과를 모아 리턴하는 형태이다.

이를 간단히 정리하자면 다음과 같다

  • Service A : 앱으로부터의 요청에 대해 n개의 A_sub에게 비동기적으로 요청을 보낸다.
  • A_sub : Service A의 요청을 받고 Database Service와 CrawlJob Service 사이에서 이를 중계하며 적절한 요청을 보낸다.
  • CrawlJob : A_sub의 요청을 받고, 지정된 Crawling 작업을 실행한 후 결과를 반환한다.

B, C Service는 A Service에 비해 크게 복잡한 부분이 없었던 만큼 큰 고민이나 큰 변화가 없었다. 반면 A는 정말 많은 고민이 있었고 위의 결과물이 나오기까지 크게 3번의 변화가 있었다.

따라서 A Service에 대한 고민과 중간 결과들을 이야기해보려고 한다.

  1. 첫 번째 버전

    msa1

    화이트 보드에 뭐라고 막 복잡하게 쓰긴 했지만 사실은 생각보다 간단하다.

    저 그림은 너무 복잡해서 다시 간단하게 도식화해보면 다음과 같다

    msa1-1

    위 API Server의 기능은 다음과 같다

    • 데이터 베이스 api에 조회 요청
    • 크롤링 요청에 대한 크롤링 결과 반환
    • 데이터 베이스 api에 크롤링 결과 저장 요청

    처음에 이런 식으로 구조를 짜니 꽤 큰 문제가 발생했다.

    1. 크롤링 관련 서버가 너무 많은 일을 분담하는 것 같다.
      • 크롤링 서버는 크롤링만 하고 결과를 반환해줘야 하는데, 데이터베이스 api와의 소통이후 여러가지 판단등 다양한 일도 한다.
      • 3가지 기능을 단일 서버가 하게 되면 자원(시간, 컴퓨팅 자원)소모가 커져 서버의 부담이 과중된다고 판단함.
    2. 앱이 각각 크롤링 서버에게 비동기 요청을 보내야한다.
      • n개의 크롤링 작업을 효율적으로 처리하기 위해 비동기로 처리하고 있다.
        • 위 그림 상 api server의 뒤로 층이 쌓인건 n개의 크롤링 대상들이 있다는 것이다.
      • 위 그림 상에서 앱이 모든 크롤링 서버에게 요청을 보내기 위해 총 3번의 request를 보내야 한다.
        • 크롤링 대상이 추가되거나 삭제된다면 앱의 코드를 수정해야하는 문제가 발생한다.

    위 문제를 해결해보기 위해 그 다음의 모양이 나왔다.

  2. 두 번째 버전

    msa2

    크롤링서버 앞단에 Gate라고 부르는 서버를 하나 두었다.

    그림에서는 표현이 안되었지만 크롤링서버는 1번과 동일하게 n개가 있다고 가정한다.

    Gate의 기능은 다음과 같다

    • 앱에서의 요청을 받고 각각의 크롤링서버로 비동기 요청을 보냄.
    • 데이터베이스의 조회 요청
    • 데이터베이스의 삽입 요청

    1번에서의 문제를 그대로 해결한 서버를 하나 만든 것이다.

    따라서 크롤링서버의 부담이 조금 덜어지고, 앱 입장에서는 하나의 요청만 보내도 뒤에 n개의 데이터들을 응답받을 수 있다.

    그런데 이 또한 완벽하지는 않았다.

    1. api 서버들이 많아지면 각 서버의 주소를 관리하기가 너무 힘들어진다.
      • 설명하고 있지는 않지만 최종 그림에서 본 것처럼 다른 서비스들도 개발이 되는 중이어서 서비스의 개수가 점점 많아지는 상황이었다.
      • 이 상황에서 요청 해야할 서비스(destination)의 주소를 요청을 보낼 서비스(source)에서 관리하다보니 많은 번거로움이 있었다.
        • 주소가 변경되면 모든 서비스들의 환경변수를 변경해줘야한다.
    2. 크롤링 서버의 부담을 덜어주기 위해 Gate라는 서비스를 도입했지만 이젠 Gate의 부담이 커지는 상황이다.
      • 크롤링 대상이 늘어날 수록 부담이 커진다.
      • 크롤링 대상이 N개라면 작업량은 xN이 된다.
  3. 세 번째 버전

    msa3

    이제 조금 더 서비스들이 많아졌다.

    Gate 와 크롤링 서버 사이에 하나의 서버를 더 두었고, 모든 서버와 통신할 수 있고, 각 서버의 주소를 알려주는 일명 Call Center 서버를 만들었다.

    Gate와 크롤링 서버 사이의 Mall 서버는 Gate의 부담을 덜어주었다.

    • Gate는 이제 각각의 Mall들에게 요청을 보낸다.
    • Mall들은 자신이 담당하는 크롤링 서버에 대한 부분만 책임지면 된다.
    • 자신의 크롤러에게 크롤링을 요청하고 데이터를 데이터베이스와 Gate에게 반환한다.
    • 결과적으로 크롤링 서버를 추가, 삭제할때 레고처럼 붙였다,땟다 할 수 있게되었다.

    Call Center서버

    • 각각의 서비스들은 자신이 요청보내고자하는 주소를 Call Center서버에 질의한 후 응답받은 주소로 요청을 보낸다.
    • 이로써 자주 바뀌는 주소에 관해 한곳에서만 관리할 수 있어 관리의 비용이 줄어들었다.

이렇게 마지막 개선까지 마친 후의 모습을 도식화 해보면 처음에 봤던 이 그림이 나온다.

msa-final

지금 생각해보면 이 구조도 문제가 참 많다…ㅎㅎ

우선 데이터베이스가 하나밖에 없고, 이를 관리하는 서비스도 하나여서 데이터베이스에서 병목현상이 발생할 수 있다.

데이터 베이스도 서비스 별로 분리하는게 좋아보이긴 하다.

또한 Call Center라는 서버를 두어 주소관리를 어느 정도 간편하게 한긴했지만 아직도 Call Center를 일일이 수정해줘야하고, 앱과 제일 먼저 만나는 Nginx서버에 하드코딩 형태로 내부 서비스들의 주소를 넣었기 때문에 이 또한 확장성이 낮다고 볼수 있다.

나중에 알아보니 Netflix가 Eureka라는 서비스를 만들어서 이를 이용해 service discovery라고 하는 문제를 해결했다고 한다. 문제 상황은 우리가 해결하려고 했던 주소 관리 문제였다. 나중에 시간되면 한번 더 공부해볼 필요가 있을 것같다.

마무리

지금까지 나와 동료들이 어떻게 ‘나름의’ MSA를 만들었는지 살펴보았다.

물론 누군가가 봤을때 아무것도 아닌것이라고 생각할 수도 있고, 저건 MSA가 아니다 라고 말할 수있다.

다 맞는 말이다.

하지만 그래도 팀원들과 함께 고민하며 저런 서비스들을 만들어보고, 개선해 나가는 점들이 너무 재밌었다. 많이 부족하긴 하지만 좋은 경험이었다고 생각한다.

또한 MSA 자체에 대해 많은 흥미를 일으키게한 프로젝트여서 앞으로 틈틈히 관련된 공부를 해보고 기회가 된다면 또 글을 써보려고 한다.

Leave a comment