# Twilio Segment가 마이크로서비스에서 모놀리식 아키텍처로 회귀한 이유

> Clean Markdown view of GeekNews topic #25065. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25065](https://news.hada.io/topic?id=25065)
- GeekNews Markdown: [https://news.hada.io/topic/25065.md](https://news.hada.io/topic/25065.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-14T23:34:03+09:00
- Updated: 2025-12-14T23:34:03+09:00
- Original source: [twilio.com](https://www.twilio.com/en-us/blog/developers/best-practices/goodbye-microservices)
- Points: 5
- Comments: 2

## Summary

Twilio Segment는 수백 개로 분리된 **마이크로서비스 구조**의 복잡성과 운영 부담을 줄이기 위해 **모놀리식 아키텍처**로 회귀했습니다. 각 데스티네이션별 서비스가 늘어나며 테스트·배포·확장 관리가 어려워지자, 이를 단일 서비스와 **모노레포**, 그리고 이벤트 처리용 **Centrifuge 시스템**으로 통합했습니다. 이 전환으로 개발 속도와 안정성이 크게 향상되었으며, Segment는 생산성과 운영 효율을 중심으로 한 단일 구조를 유지하고 있습니다.

## Topic Body

- Twilio Segment는 수백 개의 **마이크로서비스 구조**를 운영하다가 복잡성과 유지보수 부담으로 인해 **단일 서비스(모놀리식)** 로 전환함  
- 초기에는 각 **데스티네이션 API** 를 분리해 장애 격리와 확장성을 확보했으나, 서비스 수가 140개 이상으로 늘며 **운영 오버헤드**가 급증함  
- 다수의 **레포지토리와 공유 라이브러리** 관리가 어려워지고, 테스트·배포 시 전체 서비스에 영향을 주는 문제가 발생함  
- 이를 해결하기 위해 **Centrifuge 시스템**과 **모노레포 구조**를 도입하고, 테스트 자동화를 위해 **Traffic Recorder**를 구축함  
- 결과적으로 개발 속도와 안정성이 크게 향상되었으며, Twilio Segment는 **생산성과 운영 효율성**을 위해 모놀리식 구조를 유지 중임  

---

### 마이크로서비스 도입과 한계
- Twilio Segment는 고객 데이터 인프라를 위해 **마이크로서비스 아키텍처**를 채택, 각 목적별 서비스가 독립적으로 이벤트를 처리하도록 설계  
  - 수백 개의 **서버사이드 데스티네이션**(예: Google Analytics, Optimizely 등)에 데이터를 전달  
  - 초기에는 단일 큐를 사용했으나, 특정 데스티네이션 장애 시 전체 지연이 발생하는 **헤드 오브 라인 블로킹** 문제가 발생  
- 이를 해결하기 위해 각 데스티네이션별 **별도 서비스와 큐**를 구성, 장애 격리와 독립적 확장을 달성  
- 그러나 서비스 수가 늘면서 **운영 복잡도와 유지보수 비용**이 급격히 증가, 개발 속도 저하와 결함률 상승으로 이어짐  

### 개별 레포지토리와 공유 라이브러리의 문제
- 각 데스티네이션은 서로 다른 API 포맷을 사용해 **커스텀 변환 코드**가 필요  
  - 초기에는 단일 레포에서 관리했으나, 테스트 실패가 전체에 영향을 주어 **레포 분리**를 단행  
- 이후 50개 이상의 신규 데스티네이션 추가로 **50개 이상의 레포지토리**가 생김  
  - 공통 기능을 위해 **공유 라이브러리**를 도입했으나, 버전 불일치와 배포 부담이 커짐  
- 서비스별 부하 패턴이 달라 **자동 확장 설정**이 어려웠고, 운영자가 수동으로 조정해야 하는 경우도 발생  

### 모놀리식 전환과 Centrifuge 도입
- 140개 이상의 서비스를 **단일 서비스로 통합**하기로 결정  
  - 개별 큐를 대체하기 위해 **Centrifuge 시스템**을 개발, 모든 이벤트를 단일 서비스로 전달  
  - Centrifuge는 이후 Twilio Segment의 **Connections 백엔드 인프라**로 발전  
- 단일 서비스 구조로 전환하면서 **운영 부담 감소**와 **장애 대응 단순화**를 달성  

### 모노레포와 테스트 자동화
- 모든 데스티네이션 코드를 **하나의 레포지토리**로 병합, 120개 이상의 의존성을 단일 버전으로 통일  
  - 버전 관리 단순화와 유지보수 효율성 향상  
- 테스트 자동화를 위해 **Traffic Recorder**를 도입  
  - 실제 HTTP 요청·응답을 기록 후 재생하여 외부 네트워크 의존성을 제거  
  - 테스트 속도가 수 분에서 **밀리초 단위**로 단축, 안정성 대폭 향상  
- 테스트 실패율이 낮아지고, 개발자 생산성이 크게 개선됨  

### 모놀리식 구조의 효과와 트레이드오프
- 단일 서비스로 통합 후 **배포 속도와 개발 효율**이 크게 향상  
  - 1년간 공유 라이브러리 개선 횟수가 32건에서 46건으로 증가  
  - 단일 엔지니어가 수 분 내 배포 가능  
- **운영 효율성**도 개선되어, 부하 급증 시에도 대규모 워커 풀로 흡수 가능  
- 그러나 **결함 격리 어려움**, **캐시 효율 저하**, **의존성 업데이트 리스크** 등의 단점 존재  
  - 일부 손실은 **운영 단순성과 생산성 향상**으로 상쇄  

### 결론
- 마이크로서비스는 초기 성능 문제를 해결했지만, **대규모 확장과 일괄 업데이트**에는 부적합  
- 모놀리식 전환으로 **운영 안정성과 개발 속도**를 모두 개선  
- 성공적 전환을 위해 **견고한 테스트 체계**와 **트레이드오프 수용**이 필수  
- Twilio Segment는 일부 인프라에는 여전히 마이크로서비스를 유지하지만, **서버사이드 데스티네이션**에는 모놀리식이 더 적합한 구조로 평가됨

## Comments



### Comment 47804

- Author: yangeok
- Created: 2025-12-16T09:35:38+09:00
- Points: 1

모든걸 다 쪼개어 정규화시ㅣ는건 리스크가 있는 것 같아요

### Comment 47717

- Author: neo
- Created: 2025-12-14T23:34:03+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46257714) 
- 모든 목적지의 코드를 하나의 **repo**에 모으자, 단일 서비스로 병합할 수 있었음  
  그 결과 개발 생산성이 크게 향상되었음. 이제는 공유 라이브러리 하나를 수정할 때마다 140개 이상의 서비스를 배포할 필요가 없음  
  한 명의 엔지니어가 몇 분 만에 배포할 수 있게 되었음  
  만약 라이브러리 변경 때문에 모든 서비스를 다시 배포해야 한다면, 그것은 진정한 서비스가 아니라 **분산 모놀리식 구조**임  
  공유 라이브러리를 전체 서비스에 강제로 동기화해야 한다는 개념 자체가 서비스 아키텍처의 철학과 맞지 않음
  - 네 말이 일리는 있지만, 실제로는 훨씬 더 **복잡한 상황**임  
    이건 “모든 라이브러리 업데이트마다 전체 재배포”라기보다는 Amazon식 **공유 빌드·배포 시스템**에 가까움  
    중앙에서 관리되는 단일 소스에서 라이브러리를 가져오는데, 버전이 다르면 호환성 문제로 모두 마이그레이션해야 함  
    보안 취약점으로 특정 버전을 제거해야 할 때는 전체 재배포가 필요하지만, 중앙화된 관리의 이점이 훨씬 큼  
    이런 시스템은 여전히 **마이크로서비스**로 분류되지만, 비용과 운영 효율 측면에서 공유 환경처럼 동작함  
    이걸 분산 모놀리식이라 부르는 건 과도한 해석임
  - 말은 쉽지만, 실제로는 서비스 간 **미묘한 버그나 비호환성**을 유발하기 쉬움  
    마이크로서비스 패턴을 따르다 보면 배포 리스크가 늘어나는데, 처음엔 잘 안 보임  
    예를 들어 돈 관련 라이브러리의 버그를 수정했다면, 현실적으로 모든 서비스를 재배포해야 할지 고민하게 됨
  - 라이브러리를 전체적으로 업그레이드해야 한다고 해서 반드시 **잘못된 결합**이라고 볼 수는 없음  
    보안 취약점이 있는 라이브러리는 시스템 설계와 무관하게 전면 교체해야 함  
    이런 경우에는 오히려 **모놀리식 구조**가 더 다루기 쉬움
  - 공유 라이브러리 개념 자체가 모든 서비스를 **강하게 결합**시킴  
    진짜 마이크로서비스라면 메시지를 주고받고, JSON을 사용해야 함  
    코드가 아니라 **API**만 알면 충분해야 함. 그래야 각자 독립적으로 배포하고 확장할 수 있음
  - 그렇다면 140개 서비스 각각에 **로깅 코드**를 새로 써야 한다는 말인가?  
    공유 모듈을 활용하는 게 더 합리적이지 않음?

- 이전 회사에서는 모든 걸 **마이크로서비스**로 운영했고, 그 전 회사는 **AWS 서버리스**였음  
  두 경우 모두 서비스 간 통신이 가장 큰 문제였음. 계약(contracts)을 동기화하기 어렵고, 배포도 복잡했음  
  초기에는 빠르게 움직였지만, 시간이 지나면서 복잡성이 폭발했음. **공포 기반 개발**이 일어났고, 회의가 너무 많았음  
  지금 회사는 **모놀리식 구조**인데 훨씬 다루기 쉬움. 타입이 명확하고, 리팩터링이 간단함  
  자체 플랫폼 위에 구축된 **AI 에이전트**들이 코드베이스 안에서 스스로 개선되는 걸 보는 게 흥미로움  
  단점은 빌드 시간이 길다는 점뿐이지만, 도구 체인의 발전으로 2026년에는 **10배 빠른 배포**를 기대함  
  내 결론은, 모놀리식 구조 덕분에 훨씬 빠르게 성장하고 확장할 수 있었음
  - 내 경험은 정반대임. SendGrid에서 10년간 일하며 12명에서 500명 규모로 확장했는데, **서비스 아키텍처** 덕분에 가능했음  
    모놀리식 구조에서는 항상 **관심사 분리**가 깨지고, 팀 간 결합이 심했음  
    진짜 속도와 확장은 팀이 분리되어 있을 때만 가능했음  
    ORM에서 DTO로 전환하는 데 2년, 50개 팀, 150명 이상이 필요했음  
    이런 복잡한 작업은 **마이크로서비스**가 아니었다면 불가능했음

- 이 글을 보면, 문제의 핵심은 **마이크로서비스 vs 모놀리식**의 기술적 선택이 아니라  
  **엔지니어링 조직의 품질과 구조**에 있음  
  코드 저장소와 테스트 구조가 조직의 수준을 그대로 드러냄
  - 많은 팀이 **기술적 규율**이 부족함  
    “그건 하지 말자”고 말할 수 있는 사람이 없으면 복잡성이 폭발함  
    권한 있는 리더가 있어야 팀이 멈추고 생각할 수 있음
  - Twilio 프로젝트를 함께 했는데, 정말 **엉망이었음**  
    API 문제 발생 시 원인을 분석하지 않고, 데이터만 수정하고 티켓을 닫음  
    같은 문제가 반복돼도 근본 원인을 해결하지 않음
  - **Conway의 법칙**이 또 한 번 증명됨  
    인터뷰만 해도 회사의 코드베이스 구조를 어느 정도 예측할 수 있을 정도임

- 이건 진짜 **모놀리식 전환**이라기보다는 여전히 **SOA 구조**임  
  단지 서비스의 범위가 커졌을 뿐임  
  140개 서비스를 한 팀이 관리한다면, SOA는 팀 확장을 위한 구조이지 서비스 확장을 위한 게 아님  
  한 팀이 모든 공유 라이브러리를 관리하면 버전 불일치와 API 혼란이 생김  
  결국 **조직 구조가 아키텍처를 결정**함. 한 팀이 복잡성을 줄이기 위해 통합한 것임  
  이건 “모놀리식”이 아니라 **팀 단위로 적절히 범위가 조정된 서비스 수준**임  
  이런 구조가 가장 이상적이라 생각함. 팀이 커지면 다시 분리해야 함

- 나는 **마이크로서비스 지지자**는 아니지만, “모노레포 vs 마이크로서비스”의 **가짜 이분법**이 눈에 띔  
  너무 많은 도구가 서비스와 repo를 1:1로 가정함  
  하지만 모든 걸 한 repo에 두고도 독립적으로 배포할 수 있음  
  GitHub 같은 곳에서 폴더 단위로 독립된 서비스로 다룰 수 있으면 좋겠음  
  - 이전 회사에서 이걸 직접 구현했음  
    **Bazel**로 의존성 트리를 관리하고, `bazel query`로 영향받는 타깃을 찾아 테스트를 자동 실행했음  
    GitHub Actions와 연동해 PR을 차단하는 워크플로를 만들었음  
    잘 작동했지만, 구축에 몇 달이 걸렸음
  - “마이크로서비스에서 모놀리식으로 바꾸니 문제가 사라졌다”는 말이 거슬림  
    실제 문제는 **운영과 도구 부족** 때문이었음 — CI, 오토스케일링, 온콜 체계 모두 미흡했음

- 두 접근 모두 실패할 수 있음  
  Node.js나 Python 같은 환경에서는 이벤트 루프가 처리할 수 있는 코드량에 한계가 있음  
  6~8명이 200개 서비스를 관리한 적도 있고, 80명이 하나의 모놀리스를 관리한 적도 있음  
  **마이크로서비스**는 작은 변경엔 유리하지만, 전체 변경은 어렵고  
  **모놀리식**은 그 반대임  
  결국 중요한 건 아키텍처가 아니라 **추상화와 테스트, 디커플링 방식**임  
  - “하나의 비즈니스 문제를 해결하는 소프트웨어라면, 하나의 **마이크로서비스**로 묶는 게 맞음”  
    마이크로의 기준은 기술이 아니라 **비즈니스 단위**임  
    그 이하로 쪼개면 **나노서비스**가 됨
  - 이런 합리화는 결국 **런타임의 한계**를 덮는 임시방편처럼 느껴짐  
    Beam, JVM, Rust, Go 같은 환경에서는 이미 해결된 문제임
  - 이벤트 루프가 처리할 수 있는 코드량의 한계가 구체적으로 어떤 단위인지 궁금함  
    CPU 캐시 문제인가?
  - 대규모 환경에서도 정말 Node.js나 Python을 쓰는지 의문임  
    보통은 Go, Java, C#을 쓰는 줄 알았음

- 대부분의 회사에서 **마이크로서비스는 오히려 문제의 90% 원인**이었음  
  AWS, Google, Netflix 같은 거대 조직이 아니면 맞지 않음  
  시스템을 조립 가능한 단위로 나누는 것 자체가 이미 어려운데, 거기에 네트워크 경계를 추가하는 건 어리석음  
  다음 트렌드는 React나 SPA에서 벗어나 **서버 중심 전환**으로 갈 것 같음

- 마이크로서비스로 전환한 이유가 “테스트가 자주 깨져서”라니, 너무 **거꾸로 된 접근**처럼 보임  
  테스트가 깨진다고 코드베이스 구조를 완전히 바꾸는 건 이상함
  - 우리도 비슷한 문제를 겪었지만, 각 팀에 **독립된 개발 환경**을 주는 방식으로 해결했음  
    팀별로 VM과 CI/CD 설정을 분리하니, 테스트 충돌이 사라졌음  
    단점은 기능 간 충돌을 즉시 발견하지 못한다는 점이지만, 코드 소유권이 명확해 큰 문제는 없었음

- 제목에 [2018]을 추가해달라는 요청이 있었음
  - 혹시 지금은 다시 **마이크로서비스로 회귀**했는지 궁금함
  - 7년 전 글을 다시 끌어올리는 건 좀 그렇다고 생각함. 기술 세계에서는 이미 **고대사**임

- “테스트가 깨지면 관련 없는 코드도 수정해야 했다”는 이유로 repo를 분리했다는데,  
  테스트 실행 방식을 바꾸거나 수동 배포를 허용하는 등 **다른 해결책**도 있었을 것 같음  
  repo 분리가 유일한 해법은 아니었음
