ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 어쩌다 DDD 공부를 시작했다
    개발일지 2019. 3. 25. 00:24

    주말 동안 <DDD Start!>를 공부하고, Apache Kafka와 AWS Kinesis에 대해서 조금 기술조사를 했다.

    아직 어렵기만 하지만 곧 판단의 기준이 설 거라고 생각하고! 열심히 공부하고 있다.


    오늘은 DDD를 공부하게 된 계기에 대해서 생각이 나 적어보려고 한다.


    어쩌다 만난 DDD

    팀 내 테크 리더님의 추천으로 DDD를 조금씩 공부하고 있다.

    DDD를 공부하게 된 계기는 따로 있었는데...


    현재 우리가 만드는 서비스는 각 도메인별로 모듈화한 상태로 개발되고 있다.

    즉 계정, 인증, 통계 등의 문제 영역 별로 별도의 모듈 안에서 개발되고, 별도의 DB를 사용한다.

    배포도 모듈 단위로, 서로 분리된 EC2 Auto Scaling Group를 통해 이루어진다.


    -- 여기서부터 설명 어설픔 주의 --


    이렇게 하면 문제 영역 별로 의존성이 줄어들어, 모든 서버를 재배포하지 않고

    인증 서버만 재배포하거나 통계 서버만 재배포하는 일이 가능해진다.

    서로 비슷한 시점에 변경해야 하는 것들을 한데 모아두면서 더 작고 수월한 작업이 가능해진다.


    하지만 각 모듈을 외부로 노출시켜서 API 요청을 받는다고 하면,

    클라이언트측에서는 어느 서버에 어떤 요청을 보내야 할지 알아야 하는 수고로움이 생긴다.

    가령 계정 서버에 보내야 하는 회원가입 요청을 통계 서버에 보냈다면 404 Not Found가 뜰 수도 있다.

    모듈화를 시키지 않았다면 모든 요청을 한 곳에 보낸다 해도 적절한 응답을 받았을 텐데 말이다.


    따라서 모든 API 요청을 받아, 이를 적절한 서버로 중계해 주는 수문장 역할을 누군가 맡아야 한다.

    또한 계정 서버라고 해서 한 대만 두지 않으므로, 과부하가 걸리지 않도록 API 요청을 여러 대에 분배해야 하고,

    EC2 인스턴스들의 상태를 체크하면서 살아있는 친구에게만 요청을 중계할 필요도 있다.

    또 암호화된 HTTPS 요청이 들어왔을 때는 암호를 풀어줄 필요도 있다.


    로드 밸런서 등장

    이런 복잡한 작업을 하는 것이 Load Balancer이다.

    그리고 우리 회사는 AWS를 쓰므로 Elastic Load Balancing를 활용하고 있다.

    그렇다면 ELB에서는 각 API 요청에 대해서 무엇을 근거로 계정, 인증, 통계 등의 각 서버에 분배할 수 있을까?


    복잡하게 요청의 본문을 보고... 그러면 처리가 늦어진다.

    따라서 우리 팀이 현재 사용하는 ALB(Application Load Balancer)에서는 크게 두 가지만 보고 있다.


    가령 누군가 이 블로그를 보다가 개발일지 카테고리로 들어갔을 때...

    1. Host가 미리 설정한 것과 일치하는지 본다: 여기서는 millenial-dev.tistory.com

    2. Path가 미리 설정한 것과 일치하는지 본다: 여기서는 /category/개발일지


    따라서 계정, 인증, 통계 등 각 도메인별 API에 대해서 Host나 Path 둘 중 하나에는 공통적인 부분을 만들어야 한다.

    우리는 Path에 대해서 공통적인 부분을 만들기로 했다.

    계정이면 /users/*, 인증이면 /auth/*, 통계면 /statistics/*로 시작하는 식으로...


    하나에 엄청 모여요!

    그렇게 만들어진 API 목록을 확인하다가 이상한 점을 발견했다.
    가령 우리가 블로그를 만든다고 치자. 블로그의 각 게시물, 즉 콘텐츠에 관련된 API를 /contents/* 라는 Path 하위에 모아두었다.
    그런데 블로그를 만들다가 게시물별로 태그를 지정할 수 있는 기능이 생겨, /contents/tags/* 라는 Path 하위에 많은 API가 생겼고,
    결국 /contents/* 하위에는 다른 서버보다 훨씬 많은 API들이 생겨나게 되었다.

    순간 "한 곳에 몰려 있는데 이거 분리해야 하는 거 아냐?"라는 생각이 들어서,
    동료 개발자들에게 태그 관련 API들을 /tags/* 하위로 모아두고, 별도로 태그 서버를 모듈화하는 게 어떻겠냐고 물어봤다.

    그리고 대부분 부정적인 의견을 주었다. 이렇게...


    "아뇨, 이건 건드리지 않았으면 좋겠어요. 같은 도메인이니까요."

    "음... 제 생각은 달라요. 이건 같은 도메인에 속해요."


    근데 한 가지 못 알아듣는 부분이 있었다. 나 빼고 모두가 쓰고 있는 도메인이라는 말...!


    "같은 도메인이라는 게 무슨 말이지? 

    콘텐츠와 태그는 저장하는 DB 테이블도 다른데, 같은 도메인이라고 하는 이유가 뭘까?"


    라는 의문을 가지기 시작하자 거짓말처럼 알아챈 테크 리더님이 Domain Driven Design에 대한 공부를 추천해 준 것이었다.

    그리고 조금씩 공부를 하기 시작하면서, 왜 콘텐츠와 태그가 같은 도메인이라고 하는지 알게 된 것 같다.

    (정확히는 같은 Aggregate에 속하는지)


    Aggregate?

    (하도 책마다 표기법이 다르길래... 애그리게이트, 애그리게잇, 애그리거트... 그냥 영어로 적기로 했다.

    조립물이라는 번역어도 있는 듯하다)


    DDD를 공부하다 보면 Entity, Value, Aggregate, Bounded Context 등 새로운 개념들이 많이 등장한다.

    이런 개념들을 한 문단 안에 담아내는 것은 무리라서 Aggregate만 간단하게 설명하고,

    이를 통해 콘텐츠와 태그가 같은 도메인인 이유를 설명해 보려고 한다.


    큰 그림으로 보기

    우리 회사의 직원 수는 현재 약 1000명 정도가 된다. 1000명의 직원을 올림픽공원 평화의 문 앞에 모아두고,

    각 직원들 사이의 업무 흐름을 파악하려고 하면 불가능할 것이다. 인간의 두뇌로는 한계가 있기 때문이다.


    그렇다면 어떤 방법을 써야 전체적으로 회사가 돌아가는 모습을 파악할 수 있을까?

    각 직원들이 하나의 팀에 소속되어 있다고 가정하고, 팀별로 원을 만들어 모인다면 한번 관계도를 그릴 시도는 해볼 수 있을 것이다.

    이 팀은 저 팀의 API를 사용하고, 저 팀은 그 팀에게 법률 자문을 구하고, 등등...


    직원들을 팀으로 조망하듯이, 소프트웨어를 만드는 여러 객체(회원, 콘텐츠, 태그, ...)를 관련된 것끼리 묶은 것을 Aggregate라고 한다.

    그런데 관련된 객체를 묶었다는 얘기는 하나마나한 얘기다. 결국 어떻게든 서로랑 연관이 있기 때문이다.

    하나의 Aggregate를 구성하는 기준에는 좀 더 고려할 것이 있다.


    일관성 유지

    우리 회사는 대부분의 팀이 일정한 주기로 사무실 층을 옮긴다.

    블로그팀이 이번 달에 사무실을 8층에서 15층으로 옮겨야 한다고 치자. 블로그팀은 아직 이 사실을 모른다.

    블로그팀의 누구에게 이야기하고 싶은가?


    아마 팀장을 떠올릴 것이다. 팀장이라면 팀의 모두에게 전체공지를 하고 리마인딩을 하겠지만,

    나한테 얘기하면 소심해서 팀의 모두에게 전달을 못할지도 모른다. 

    그러면 누군가는 미처 짐을 싸지 못하고 8층에 남는 참사가 일어난다.


    소프트웨어 또한 특정 작업에 대해서는 연관된 데이터의 일관성을 유지해야 한다.

    가령 태그별로 등록된 콘텐츠 개수를, 성능을 높이기 위해 태그 객체에 저장하고 있다고 해 보자.

    이 경우 새로운 콘텐츠가 등록되었을 때는 태그 객체도 수정될 필요가 있다.


    이때 코드의 어딘가에서 멋대로 새로운 콘텐츠를 생성하고 저장해버리면,

    태그 객체에 저장된 콘텐츠 개수와 실제 콘텐츠 개수가 어긋나 버린다.

    이런 상황이 바로 데이터의 일관성이 깨진 상태이다.


    데이터의 일관성을 유지할 수 있으려면 콘텐츠와 태그를 하나로 묶어 관리해야 한다.

    따라서 둘은 같은 Aggregate로 보는 것이 적절하다.


    같은 생명 주기

    또한 태그가 언제 생기고, 언제 변경되는지를 살펴볼 필요가 있다.
    연관 콘텐츠도 없는데 태그가 먼저 생길 수는 없다. 태그는 반드시 어떤 새로운 콘텐츠와 같은 시점에 생겨난다.
    그리고 콘텐츠가 등록되면 태그별로 등록된 콘텐츠 개수도 바뀌어야 한다. 즉 태그는 콘텐츠와 같은 시점에 변경된다.
    이렇듯 비슷한 시점에 생겨나고 변경되고 사라지는 객체들은 같은 Aggregate에 속하는 것이 적절하다.

    반대의 예로 회원콘텐츠를 생각해 보자.
    한 명의 회원이 여러 콘텐츠를 소유한다고 생각하면 같은 Aggregate로 볼 수도 있겠지만,
    회원가입을 했다고 콘텐츠가 생겨나지는 않는다. 또 회원정보를 변경했다고, 회원을 탈퇴했다고 콘텐츠가 영향을 받지는 않는다.
    따라서 회원과 콘텐츠는 다른 Aggregate로 보아야 할 필요성이 크다.


    어떻게 공부하나

    이런 개념을 알고 나서는 DDD가 꽤 매력적이라는 생각을 하게 된 것 같다.

    아직 끝판왕이라는 에릭 에반스의 책을 읽을 엄두는 안 나서 <도메인 주도 설계 핵심>을 먼저 읽었고,

    좋은 내용이지만 여전히 모호한 것 같아 <DDD Start!>를 읽고 있다.


    <DDD Start!>는 선수 지식을 조금 요구하지만, 다행히 회사에서의 개발 경험을 통해 익숙하게 느끼는 부분들이 있어서 좋다.

    특히 개발자를 이해시키는 데에는 코드만한 게 없는 것 같다. 코드 수준에서 설명을 보완하니까 바로바로 이해가 된다.

    장단점이 있겠지만, 빠르게 이해할 수 있어서 지금으로서는 좋다고 느끼고 있다.


    이제 주말도 마무리해야 하고... 어떻게 하면 더 일을 잘할 수 있는지 고민스럽다.

    블로깅도 그렇고 일을 잘 할 수 있는 방법을 고민하는 것도 소홀했는데,

    다시 조금씩 발전할 수 있는 한 주가 되었으면 좋겠다.

    '개발일지' 카테고리의 다른 글

    회사에 와서 보이는 지식이 있다  (3) 2019.01.24
    미안해하지 않을 방법  (0) 2019.01.18
    일에서 배우고 기록한다  (0) 2019.01.18
    작명이 코드가 된다  (0) 2019.01.17
    기술 배우는 타이밍  (0) 2019.01.16
Designed by Tistory.