카카오뱅크의 지속적인 성장에 따라 기술부문에서는 개발 리소스 부족과 빌드시간 증가가 점차 중요한 이슈가 됐습니다. 이러한 어려움을 해결하기 위해 모듈화를 적극 도입하여 업무에 적용하기 시작했는데요. 이 글에서는 iOS 개발자들이 채택한 모듈화에 대해 간단히 말씀드리고, 그 과정에서 느낀 점과 교훈 등을 소개하고자 합니다.
들어가며
안녕하세요. 카카오뱅크 결제캠프의 결제서비스개발팀에서 iOS 개발을 담당하고 있는 Zeon입니다.
저는 얼마 전에 열린 KWDC(Korea Wide Developers Conference)에 세션 연사자로 참여해 카카오뱅크 iOS 플랫폼의 모듈화 현황과 진행과정, 그리고 관련 고민을 공유했습니다. 발표 준비만으로도 떨렸지만, 카카오뱅크가 KWDC의 공식 후원사로 참여했기 때문에 더욱 이렇게 많은 분들께 발표 내용을 공유드리는 점이 뜻깊다고 생각했는데요. 그만큼 양질의 내용으로 잘 준비해야겠다는 책임감이 더해졌습니다. 걱정과 기대가 교차하는 다양한 감정 속에서 발표를 준비했던 그때가 아직도 잊혀지지 않네요.
이 글에서는 제가 KWDC에서 발표한 내용과 왜 ‘모듈화’라는 선택을 하였는지에 대한 설명을 중점적으로 정리해 보았는데요. 현재 모듈화에 대해 고민하고 계신 분들에게 도움이 되기를 바라며 시작하겠습니다.
1. 모듈화를 왜 시작하게 되었을까요?
먼저 카카오뱅크 iOS 플랫폼에서 진행했던 모듈화의 배경과 주요 고려사항들에 대해 말씀드리겠습니다.
1) 매년 급증하는 코드양
카카오뱅크는 ‘같지만 다른 은행’이라는 슬로건을 걸고, 2017년도에 모바일 은행 서비스를 출시한 이후 빠르게 성장했습니다. 출시 7년 만에 시중은행의 모바일뱅킹 고객 수를 훌쩍 뛰어넘어 이제는 2,000만이 넘는 고객을 보유한 거대한 금융 플랫폼이 되었죠. 이렇게 많은 사용자들에게 편리하고 안정적인 금융 서비스를 제공하기 위해 수많은 신규 서비스들이 개발되고 있으며, 지금도 코드량은 계속해서 늘어나고 있습니다.
얼마나 많은 코드양의 증가가 있었고, 왜 모듈화를 고민할 수밖에 없었는지를 숫자로 확인하실 수 있도록 발표의 일부를 인용해 왔습니다.
21년도에는 123만 라인으로 14만 라인이 증가했습니다.
22년도에는 158만 라인으로 21년 대비 35만 라인이 증가했습니다.
마지막으로 올해 6월까지의 코드 라인수는 197만 라인으로 22년 대비 39만 라인이 증가했습니다.
다시 말해, 23년 상반기 동안 생산된 코드양이 22년 한 해 동안 생산된 코드량을 넘어섰다는 이야기입니다.
2) 요구되는 개발 리소스 증가
은행의 성장함에 따라 고객층은 점차 다양해지고, 이들을 사로잡기 위한 위한 신규 서비스 출시에 대한 수요도 점차 증가했습니다. 26주 적금, 모임통장 등 이제껏 없었던 새롭고 편리한 상품이 출시될수록, 다음번 신규 서비스를 바라보는 사람들의 기준도 점점 더 높아졌는데요. 높은 품질을 갖춘 신규 서비스를 출시하기 위해서는 개발 리소스가 탄탄하게 뒷받침되어야 합니다. 하지만 개발자 리소스는 단기간 안에 쉽게 늘릴 수 있는 문제가 아니었죠.
그래도 처음에는 iOS 개발자를 더 공격적으로 채용해보고자 했습니다. 그리하여 적극적으로 iOS 개발자 채용을 진행했고, 다행히도 이 시기에 여러 훌륭한 개발자분들을 팀에 모시게 되었습니다. 이렇게 모인 개발자들은 전례 없는 속도로 훌륭한 코드를 거침없이 생산하게 됩니다.
이렇게 거침없이 생산된 코드들에 의해, 빌드 시간은 점점 더 늘어나게 됩니다. 클라이언트 개발에서는 개발 과정에서 로컬 빌드를 수도 없이 하기 때문에, 이로 인한 빌드 시간 증가는 자연스럽게 개발 기간 증가로 이어졌습니다. 결과적으로 유지보수 비용과 테스트에 대한 부담이 증가하였고, 가장 안타까운 점은 iOS 개발자들 뿐만 아니라 이를 기다리는 모두의 근무시간까지도 증가하게 되었다는 것이죠. 😇
이러한 난관들을 어찌어찌 헤쳐나가며 개발하고 상품을 출시하고 있었습니다만, 프로젝트가 증가할수록 코드의 규모는 계속해서 커지고 있었습니다. 끝이 보이지 않는 악순환의 고리에 빠지게 된 것이죠. 그렇게 모듈화를 고민하게 됩니다. 그 당시의 어려움과 고민에 대한 더 자세한 이야기는 if(kakao) 2022 컨퍼런스에서 카카오뱅크 iOS 개발자 Damon 발표했던 영상 에서도 확인하실 수 있습니다.
3) 파일이 증가하면 Xcode도 힘들어 😰
우리는 파일 개수가 증가하면서 생겼던 재미있는 문제를 발견할 수 있었습니다. 위 에러로 인해서 빌드 실패를 경험했던 것인데요. 위 에러는 개인 개발머신에서도, CI머신에서도 경험할 수 있었습니다. Argument list too long은 인수 목록이 너무 길어서 발생하는 오류입니다.
더 자세히 얘기해 보자면, Xcode는 build할 때 swift 컴파일러의 빌드 실행 명령어를 호출합니다. 이 명령은 한 줄에 여러 인수들을 포함하여 호출하도록 되어있는데, 세부내용을 살펴보니 파일 하나하나를 인수로 전달하고 있음을 확인할 수 있었습니다. 이는 함수 호출의 길이 제한 때문에 발생하는 문제인데요. 이 제한은 OS level에서 설정하고 있고, 시스템 전체의 제한으로 작동하며, 단일 프로세스에 전달할 수 있는 최대 바이트 수를 정의하는데 사용됩니다.
앞서 언급한 대로 빌드 명령을 요청할 때는 파일마다 인수로 전달하는데, 상대경로가 아닌 절대경로를 전달하고 있었습니다. 이는 파일이 많을수록, 그리고 path의 깊이가 깊을수록, 이 문제가 발생할 가능성이 점점 높아진다는 것을 의미합니다.
결국 이러한 이유 때문에 우리는 모듈화를 할 수밖에 없었고, 선택과 집중을 해야 했습니다.
2. 카카오뱅크 모듈화 현황 (2023년 ver.)
1) 모듈 개수
20년에는 모듈 개수가 43개였습니다. 21년에는 49개로 6개가 늘어났고 22년에는 104개가 급증하여 154개가 되었습니다. 우리가 모듈화를 시작하게 된 시기가 22년이기 때문입니다. 마지막으로 올해 6월까지의 모듈 개수는 319개입니다. 단 6개월 만에 166개가 늘었습니다. 이는 22년 동안 생산된 개수보다 많습니다. 산술적으로만 보면 한 달에 약 28개씩, 하루에 1개 안팎의 모듈이 생겨나고 있는 것이죠.
우리는 최신 모듈 현황 자료를 활용하여 모듈 개수의 의미에 대해 생각해 볼 수 있었습니다. 모듈이 많다는 것이 더 나은 성과를 의미하는지에 대한 의문이 생겼죠. 이런 질문에 대한 고민을 토대로 이후 내용을 소개하겠습니다.
2) 빌드 속도의 개선
위 자료는 우리가 모듈화를 하면서 과거보다 더 빠른 빌드할 수 있다는 결과를 보여주고 있습니다. 심지어 모든 소스코드를 빌드해야 하는 Full Build 시간도 줄어드는 것을 확인할 수 있었죠. 이는 Swift 컴파일러에게 컴파일을 요청 및 관리하는 Xcode 빌드 시스템과 연관이 있습니다. 지속적으로 빌드 시스템이 개선되고 있고, 그 결과를 모니터링하여 이에 최적화된 설계와 개발을 진행한다면 빌드 시스템을 더욱 효율적으로 사용할 수 있습니다.
더 자세한 이야기는 Apple사의 WWDC 2022에서 소개된 Demystify parallelization in Xcode builds 영상에서 확인하실 수 있습니다.
3. 모듈 기준 정의하기
아키텍쳐 디자인 패턴과 모듈의 관계
카카오뱅크에서는 모바일 cross-platform 아키텍처 프레임워크인 RIBs(Router, Interactor, and Builder) 아키텍쳐 패턴을 사용하고 있습니다. RIBs에 대한 자세한 내용은 공식 문서를 통해 더 자세히 확인하실 수 있습니다.
먼저 맨 위의 RIB을 생성했다고 가정해 봅시다. RIB은 구조적으로 다른 RIB을 라우팅할 수 있습니다. 그리고 1개 이상의 RIB을 의존시킬 수 있습니다. 상황에 따라 다른 RIB을 라우팅할 수 있는 것이죠. 그렇게 연속된 연결고리에 의해 여러 깊이로 RIB을 의존시킬 수 있습니다. 이런 트리구조를 RIBs에서는 ‘RIB트리’ 또는 ‘상태트리’ 라고 말합니다.
이와 같이 의존성을 명확히 분리해서 주입해 주는 형태의 RIB은 모듈화에 적합해 보였고, 실제로도 많은 도움이 되었습니다. 그러나 이에 따른 새로운 고민들이 등장했습니다. 예를 들어 RIB과 모듈 기준의 관계는 어떻게 설정해야 할까요?
하나의 모듈에 모든 RIB을 두면 어떨까요? 특정 RIB이 여러 RIB에 공통으로 사용되는 경우, 모듈화로 인한 장점을 충분히 얻기는 어려워 보입니다. 반면에 공통으로 사용되는 RIB을 모듈화 하면, Task를 명확하게 나눌 수 있기 때문에, 최종 빌드 속도에 좋은 영향을 줄 수 있습니다.
그럼 적당히 한 번 나눠볼까요? 이건 의존성과는 무관한 모듈 분리입니다. B모듈은 A모듈에서 의존하고 있지만, 모든 RIB이 C모듈을 의존하고 있지는 않기 때문입니다.
그럼 이건 어떤가요? 이렇게 의존도를 생각하다 보면, 너무 많은 모듈을 만들어야 될 수도 있으므로, 오히려 생산성이 떨어지진 않을까요? 이외에도, 기능 또는 과업단위로 모듈을 만들면? RIB 단위는? 화면 단위로는? 등등 정말 다양한 질문들 속에서 모듈화를 진행하게 됩니다.
많은 비교와 숙고 끝에 저희는 다음과 같은 결론을 내렸습니다.
가장 적절한 구조를 찾기 위한 과정일 뿐 정답은 없다. 카카오뱅크 iOS 개발자 일동
정답은 없지만 가장 적절한 구조를 찾는 과정에서 다음과 같은 3가지를 가장 중요하게 고려했습니다.
- 빌드 프로세스의 이해: Apple은 지속적으로 Xcode 빌드 시스템을 발전시켜 나가고 있습니다. 이를 모니터링하면서 어떻게 설정해야 우리 프로젝트에 이득이 되는지 끊임없이 테스트하고 연구해야 합니다.
- 프로젝트 전반의 의존성 관계 이해: 프로젝트 전반의 의존성 관계를 이해해야 합니다. 프로젝트 모듈화 설계의 기본이기 때문입니다.
- 병렬 빌드 관점에서 득실 유무 판단: 병렬 빌드 관점에서 득실 유무를 판단할 줄 알면 더 빠른 빌드를 위한 구조 설계에 매우 큰 힘이 됩니다.
이렇게 카카오뱅크의 iOS 모듈화의 기준이 어떻게 정의되었는지에 대한 설명을 마무리하겠습니다.
4. 모듈화에 대한 회고
1) 도전정신
모듈화를 선행해서 도입해 본 결과들 즉, 레퍼런스 찾기가 굉장히 어려웠습니다. 특히 한국에서 모듈화를 진행하는 조직이나 회사를 찾기 어려웠고, 모듈화에 대한 커뮤니티도 활발하지 않았기 때문입니다. 그리고 모듈화에 대한 기준과 구조를 협의하는데 상당한 시간이 소요되었습니다. 여러 가지 의견들을 수렴하고 결정하는 데 있어서 엄청난 커뮤니케이션 코스트와 노력이 요구됩니다. 마지막으로 러닝커브에 따른 트레이드오프를 감당해야 했습니다. 이 부분은 주변 동료분들이 그 중요성을 인지하고 지원해 주셨기 때문에 가능했다고 생각합니다.
2) 자부심
도전적인 과제를 수행하며 자부심을 느끼게 됐습니다. 대규모 프로젝트에서만 경험할 수 있는 심도 깊은 모듈화 과정을 수행하며, 결과적으로 코드 응집도가 높아지고, 결합도는 낮아져서, 빌드 속도 증가를 통한 개발 생산성이 증대되었습니다. 무엇보다 우리 프로젝트가 규모 측면에서 가장 잘 절충된 모듈화 프로젝트라고 생각하며 업무에 임하고 있습니다.
이렇게 ‘도전정신’ 과 ‘자부심’ 이라는 2가지 키워드로, <카카오뱅크 iOS 플랫폼은 왜 모듈화를 할 수밖에 없었는지>에 대한 회고를 정리해 보았습니다.
마무리
외부에서 많은 분들이 “카카오뱅크 iOS앱” 하면 어떤 게 떠오르냐는 질문에 “모듈화” 를 많이 이야기해 주십니다. 모듈화 외에도 카카오뱅크 iOS 앱에는 견고하고 검증된 기술들이 많이 사용되고 있는데요. 그중에서도 iOS 모듈화는 카카오뱅크가 가장 잘하고 있다고 생각하기 때문에, 이번 기회를 통해서 우여곡절 끝에 얻게 된 소중한 노하우 를 여러분께 전달드리고 싶었습니다.
아마 개발자분들은 각자의 위치에서 모듈화에 대한 고민들을 많이 하실 텐데요. 이 글이 조금이나마 도움이 되셨길 기대합니다.
그래도 해답을 찾기 어려우셨다면…? 저희와 동료가 되는 것도 방법이지 않을까요? 😉
이 글을 읽어주신 분들과도 언젠가 함께 일하며 성장해나가고 싶은데요. 이 글의 주제인 iOS 모듈화에 관심이 있는 분이라면, 카카오뱅크 iOS개발자 채용 공고에 많은 지원 부탁드립니다. 긴 글 읽어주셔서 감사드립니다.