모놀리스

Monolith

개념

제품의 모든 기능을 한 덩어리에 담아 한 번에 서버에 올리는 구조로, 대부분의 서비스가 여기서 출발합니다.

등장 배경

한동안 이 구조에는 이름이 없었습니다. 소프트웨어는 원래 한 덩어리로 만들어 한 번에 올리는 것이었으니 따로 부를 이유가 없었습니다. 이름은 다른 방식이 생기고 나서 붙었습니다. 기능별로 잘라 따로 올리는 마이크로서비스가 퍼지자, 그것과 구분해 원래 방식을 가리킬 말이 필요해진 것입니다.

이름이 없던 동안 설계 회의는 자주 헛돌았습니다. 한 사람이 "지금 구조로는 안 됩니다" 라고 하면 다른 사람이 "지금 구조가 뭔데요" 라고 되물었습니다. 앞사람은 배포 단위가 하나라는 사실을 말하고 있었고 뒷사람은 코드가 정리되지 않았다는 뜻으로 들었습니다. 둘은 다른 이야기인데 같은 말로 오갔습니다.

모놀리스라는 이름이 하는 일은 그 혼선을 끊는 것입니다. 코드의 품질이 아니라 배포 단위가 몇 개냐만 가리킵니다. 이름이 생기고 나서야 "구조를 바꾸자" 는 말이 "배포 단위를 쪼개자" 인지 "코드를 정리하자" 인지 구별되기 시작했습니다.

작동 방식

한 덩어리라는 말은 네 가지가 하나로 묶여 있다는 뜻입니다.

  1. 코드가 한 곳에 있습니다. 결제, 알림, 문서 저장이 같은 프로젝트 안의 다른 폴더에 들어 있습니다.
  2. 빌드가 한 번입니다. 빌드는 사람이 쓴 코드를 실행 가능한 결과물로 만드는 과정인데, 알림 코드 한 줄을 고쳐도 결제를 포함한 전체가 다시 만들어집니다.
  3. 실행이 한 프로세스입니다. 서버 위에서 프로그램 하나가 돌고 그 안에 모든 기능이 들어 있습니다.
  4. 데이터베이스를 함께 씁니다. 문서 표와 결제 표가 같은 데이터베이스 안에 있어서 한 번의 질의로 양쪽을 같이 읽을 수 있습니다.

이 묶임이 좋게 작동하는 쪽부터 보면, 기능끼리 말을 거는 비용이 사실상 0입니다. 알림 기능이 문서 정보를 알아야 하면 함수를 그냥 부르면 됩니다. 쪼갠 구조에서는 같은 일이 네트워크 요청이 되고, 그 요청이 실패하면 어떻게 할지까지 정해 둬야 합니다.

같은 묶임이 나쁘게 작동하는 쪽은 그 반대입니다. 배포가 한 덩어리라서 알림 문구 하나를 고쳐도 결제까지 같이 올라갑니다. 그래서 배포 전 확인해야 할 범위가 고친 곳이 아니라 전체가 되고, 한 팀의 문제로 다른 팀의 배포까지 되돌아갑니다. 트래픽이 검색 기능에만 몰려도 전체를 복제해 서버를 늘려야 하니 확장성 면에서 낭비가 생깁니다. 한 기능의 메모리 누수가 프로세스 전체를 멈추기 때문에 그 프로세스가 곧 단일 장애점이 됩니다.

쓰이는 곳

처음 만드는 제품은 대개 여기서 시작합니다. 무엇을 만들지 자주 바뀌는 시기에는 기능 사이의 경계가 어디인지 아직 모르는데, 모르는 경계를 따라 미리 잘라 두면 두 달 뒤에 그 선을 다시 그어야 합니다. 한 덩어리 안에서는 폴더를 옮기는 일이지만 쪼개 놓은 뒤에는 서비스를 통째로 합치는 일이 됩니다.

팀 크기도 기준이 됩니다. 개발자 열 명 안팎까지는 배포 대기줄이 길지 않아 한 덩어리로도 불편이 적습니다. 반대로 이 구조가 버거워지는 신호는 대개 셋입니다.

  1. 빌드와 검사에 걸리는 시간이 길어집니다. 3분이던 것이 25분이 되면 하루에 배포할 수 있는 횟수가 줄고, 줄어든 만큼 한 번에 올리는 변경이 커집니다.
  2. 배포가 줄을 섭니다. 같은 날 세 팀이 각자 기능을 올리려고 대기하고, 한 팀의 문제로 셋 다 밀립니다.
  3. 같은 파일을 여러 팀이 고칩니다. 합칠 때마다 충돌이 나고, 결합도가 높아져 알림 쪽 수정이 결제 쪽을 깨뜨리는 일이 반복됩니다. 결합도는 구성 요소가 서로에게 얽혀 있는 정도를 가리킵니다.

이때 선택지는 둘입니다. 배포 단위를 쪼개 마이크로서비스로 가거나, 배포는 한 덩어리로 두고 안쪽만 모듈로 가르는 것입니다. 앞쪽은 서비스마다 배포와 감시를 따로 갖춰야 해서 그 일을 맡을 사람이 있어야 하고, 뒤쪽은 응집도를 높이는 작업만으로 배포 대기줄 말고는 대부분의 불편을 없앨 수 있습니다. 응집도는 한 모듈 안의 코드가 한 가지 일에 모여 있는 정도입니다.

실무 용례

"지금은 모놀리스로 가죠. 경계가 어디인지도 모르는데 먼저 자르면 나중에 다시 붙여야 해요."

초기 단계라 쪼개는 값을 아직 치르지 말자는 제안입니다.

"모놀리스라서 느린 게 아니라 테스트가 없어서 배포가 무서운 겁니다."

구조 탓으로 돌리는 진단을 바로잡는 말입니다.

"결제만 떼어 내고 나머지는 모놀리스로 남깁니다."

전부 쪼개는 대신 문제가 되는 부분만 분리하겠다는 계획입니다.

페이지덱은 구성원 45명 가운데 개발자가 열두 명이고, 아직 한 덩어리로 돌아갑니다. 지난 분기에 태오가 쪼개는 안을 들고 왔는데, 근거는 빌드가 22분까지 늘었다는 것이었습니다. 지현이 되물은 것은 그 22분 중 얼마가 정말 필요한 검사인가였고, 확인해 보니 절반 가까이가 매번 같은 결과를 내는 오래된 검사였습니다.

정리 후 빌드는 9분이 됐고 쪼개는 계획은 한 해 뒤로 미뤄졌습니다. 다만 문서 변환 기능만은 따로 떼어 냈습니다. 변환이 도는 동안 서버 메모리를 크게 먹어서 그때마다 다른 요청까지 느려졌기 때문입니다. 구조를 바꾸는 근거는 규모가 커졌다는 느낌이 아니라 이렇게 특정할 수 있는 증상입니다.

흔한 오해

모놀리스를 낡은 구조로 읽는 경우가 가장 많습니다. 마이크로서비스가 나중에 나왔으니 앞엣것이 구식이라고 짐작하기 쉽습니다. 하지만 둘은 세대가 아니라 맞바꿈의 관계입니다. 한쪽은 쪼개는 값을 치르고 독립 배포를 얻고, 다른 쪽은 그 값을 안 치르는 대신 배포를 같이 합니다. 개발자 열두 명이 서비스 스무 개를 굴리면 그 팀은 기능 대신 배포와 감시 설정을 만들며 분기를 보냅니다.

코드가 엉켜 있는 상태를 가리키는 말로 읽는 것도 흔합니다. 실제로 오래된 모놀리스 중에 그런 것이 많아서 두 가지가 같이 떠오릅니다. 그러나 이 말은 배포 단위가 하나라는 사실만 가리킵니다. 안쪽이 모듈로 잘 갈라져 창구를 통해서만 서로를 부르는 모놀리스도 있고, 잘게 쪼개 놓고도 서로 데이터베이스를 직접 들여다보는 마이크로서비스도 있습니다. 둘을 같은 말로 묶으면 진단이 어긋납니다. 코드가 엉킨 것이 문제인데 배포를 쪼개면, 엉킨 코드가 네트워크 너머로 흩어져 원인을 찾기가 더 어려워집니다.

자주 헷갈리는 용어

용어무엇을 가리키는가모놀리스와의 차이
모듈러 모놀리스한 덩어리로 올리되 안을 모듈로 갈라 둔 구조배포 단위는 같습니다. 모듈끼리 정해진 창구로만 부르도록 코드 단계에서 막아 둔 점이 다릅니다
모노레포여러 프로젝트를 저장소 하나에 모아 두는 방식코드를 어디에 두느냐의 문제라 배포 단위와 무관합니다. 모노레포 안에서 서비스를 열 개로 쪼개 올릴 수 있습니다

같이 보면 좋은 페이지

마지막 업데이트 2026-09-16