본문 바로가기

주저리주저리

팀 내 MSA 개선하기

팀에 처음 조인한 5년 전부터 우리 팀은 Kubernetes를 사용하고 있었다.
조인한 지 1년만에 Kubernetes는 업계 표준 오픈소스가 되었고, 우리 팀은 마이크로서비스가 서비스 개발하는데 필수라고 확신했다. 개발 프로세스를 명시적으로 관리하는 사람이 없었기 때문인지 5년 동안 우리가 도입한 마이크로서비스 개발 방식에 다음 현상이 발생했다.

  • 마이크로서비스 당 담당 개발자 1명이 배정되었다.
  • 모든 마이크로서비스가 폴리글랏했다.
    • 모든 개발자가 각자 선호하는 언어로 개발을 했다.
    • 모든 개발자가 각자 선호하는 프레임워크로 개발을 했다.

개발 속도는 괜찮았다.
일단 R&R이 정해지면 담당 개발자가 마이크로 서비스에 기능 하나 추가하면 될 일이었다.

그러나, 이런 현상은 다음 문제의 원인이 되었다.

  • 사내 GitHub ORG에 수많은 Repository가 생성되었다.
  • 성장이 멈췄다. 같은 기술을 사용하는 사람이 누군지 찾기 어려우니 모든 성장은 개인의 역량에 달렸다.
  • 코드 리뷰를 가장한 LGTM만 쌓였다. 
  • 사내에 어떤 마이크로서비스가 있는지 파악할 수 없었다
  • 개발자가 이탈하면 해당 마이크로서비스의 운명을 정해야 했다.
  • 마이크로서비스 설계가 개인에게 위임됐고 중심없는 API 스펙이 생성됐다.
  • 성장이 멈춘, 방향을 잃은 개발이 개발자 이탈에 한 몫 한다고 본다.

올 해, 12명 정도 되는 파트에 배정이 되었다. 내 주 역할은 통합된 시스템 설계, 서비스 스켈레톤 코드 구축 및 개발 주도라고 생각했다. 그 외에 개인적인 욕심으로 조직문화 (특히 개발프로세스) 개선, 적극적인 코드 리뷰, 개발 방법론 공유를 생각하고 있다. 


파트장님은 서비스 목적 상 다른 팀과의 커뮤니케이션 업무가 많아 세부적으로 개발 프로세스 및 설계에 깊게 관여할 수 없었다. 파트장님께 맡고 있는 컴포넌트에 대한 프로세스와 설계 결정을 위한 내부 회의를 하겠다고 하자, 파트 전체에 도입할 수 있도록 파트 전체로 공유해달라고 하셨다. 내가 한 일은 다음과 같다.

  • 파트장님과 파트원들께 스크럼 기반의 프로세스를 세부적으로 작성해서 공유했다.
    • R&R을 명확히 구분했다. PO, SM, Member, Operator로 나누었고 Operator는 매 스프린트마다 로테이션하기로 했다.
      (그러나 내부 조직 구조가 Align되어 있지 않아 PO 역할을 파트장님과 SM이 역할을 나눠야할 것 같다.)
      • 왜냐하면,,
        • 각 마이크로서비스 개발자가 모든 커뮤니케이션도 해야했는데 이런 업무는 개발 속도를 느리게 만드는 요소라고 생각했다.
        • 우리 조직은 정말 마이크로해서 개발자의 책임이 너무 많이 모여있다. 이 부분을 명확히 분리하여 개발에 집중하게 하고자 했다... 정해주지 않으면 의욕이 넘치는 한 분에게 업무가 과중되는 것을 자주 목격했다.
    • 정말 명확히 해야 했다. 프로세스 관리 툴 (Slack, JIRA, Confluence) 선택부터 JIRA 티켓 생성법, 스프린트 플래닝, 회고 때는 일하지 말기. 스케줄. 최대한 명확히 작성했다.
      • 예전에 한 존경하는 팀장님이 이런 이야기를 한 적이 있다. "가이드는 있어야겠지만 가이드는 참조용도로만 사용해야 한다."
        100% 공감한다. 하지만 가이드가 없으면 아웃풋은 0~100%, 가이드가 있으면 아웃풋은 70~100%가 나온다고 생각한다. 그리고 가이드는 명확해야 한다. 누구든 가이드만 본다면 쉽게 프로세스에 온보딩될 수 있도록.
    • OKR을 기준으로 프로세스를 진행하기로 했다.
      • 리뷰와 회고를 굳이 구분하지 않았다. 하루종일 가벼운 마음으로 허심탄회하게 회고하려 한다.
      • 단, OKR을 통해 목표를 상기하고 Key Result Impact을 정량화하여 스프린트를 평가하고, 목표에 Align되지 않은 업무는 과감히 쉬운 방법으로 가기로 했다.
    • 파트원들의 반응이 생각보다 좋았다. 공유 후 반응에 따라 포기하려고 했는데 생각보다 내가 말한 프로세스의 필요성에 공감해주시는 분들이 많았다.
      • 사내 애자일 코칭 팀에 연락하여 코칭을 받기로 했다.
  • DDD를 도입했다.
    • 예전에 스프린트 진행하면서 설계를 한 스프린트 백로그를 구체화하는 것이 쉽지 않았다.
    • 설계를 할 때마다 스프린트의 백로그 아이템을 변경해야하는 이슈가 잦았다.
    • 비교적 짧은 시간 (스프린트 플래닝) 에 마이크로서비스 별 요구사항을 도출할 수 있는 DDD의 Eventstorming Workshop 방식을 사용해보기로 했다.
      • 단 스프린트 플래닝은 정말 백로그 아이템 추출에만 전념해야한다.
      • API Spec이나 Event가 명확히 정의되지 않은 경우, 같은 스프린트에 설계와 개발을 함께 진행하지 않는다.
  • 함께 개발할 분들과 기술 스택을 통일했다.
    • 마이크로서비스는 서비스간 폴리글랏이 특성이다. 그러나, 같은 팀 내부에서까지 기술스택에 사일로가 발생하면 안 된다고 생각했다. 함께 성장하고 싶다.
    • 기술 스택은 다른분들과 이야기한 결과 그나마 공통점이 있는 것이 Java, Python이었다. 결론적으로 아래와 같이 정리하였다.
    • API + Messaging: 마이크로서비스는 Spring MVC + GCP Pubsub을 통한 Message-driven Architecture를 도입한다. 응답이 필요한 인터페이스 (Sync)는 Rest Controller를 통해, 응답이 필요 없는 인터페이스 (Async)는 Message-driven으로 처리하기로 한다. 헥사고날 아키텍쳐를 참고했다.
    • Serverless: 간단한 작업, 특히 GCP Managed Service 연계는 GCP Cloud Functions으로 하되 Python으로 개발하기로 한다.
    • Pipeline: Composer (Airflow)를 사용하여 Pipeline을 개발하고 스케줄링한다.
    • Data Processing: Spark Scala vs Python Dataflow (Apache Beam)를 고민 중인데 이 부분은 파이프라인 개발 경험이 많으신 분께 위임했다. -> Dataflow, 즉 Apache Beam을 선택하게 되었다.

주변 분들이 위 사항들을 자세히 정리해놓은 컨플루언스 페이지를 보고 경과를 궁금해하신다.

이제 막 시작인데 어떻게든 이 프로세스를 성공적으로 이끌어서 문화로 만들고 싶다는 욕심이 든다.