들어가며
안녕하세요! 코어 플랫폼(Core Platform) 팀 백엔드 엔지니어 차주훈입니다. 저희 코어 플랫폼 팀의 미션은 “안정적이고 확장 가능한 기술적 토대를 구축하는 것”입니다.
잡플래닛 서비스는 10년간 Ruby On Rails로 운영되고 있습니다. 긴 기간만큼 많은 라이브러리(특정 기능을 가진 코드의 묶음)들이 설치되고 쌓여 왔습니다. 각 라이브러리는 서로가 서로를 필요로 하며 의존하는 특징 때문에 관리되지 않은 라이브러리들은 복잡하게 꼬여 ‘의존성 지옥’을 만들게 됩니다.
‘의존성 지옥(Dependency Hell)’은 라이브러리 간의 꼬임이 심각하여 기술적 발전이 어려운 상황을 뜻합니다. 장기간 운영된 코드 베이스에서 흔히 앓는 현상입니다. 심한 의존성 지옥에 빠질 경우 울며 겨자 먹기로 프로그램을 처음부터 다시 만드는 절차를 밟기도 합니다.
저희는 이번에 전체 라이브러리를 분석/정리 해냈고 꼬인 의존성을 풀어가고 있습니다. 잡플래닛이 이 문제를 어떻게 해결하고 있는지 소개해 드리려 합니다. 의존성 관리의 어려움은 잡플래닛만의 문제도 특정 프로그래밍 언어만의 문제도 아닙니다. 모든 프로젝트가 겪는 어려움인 만큼 저희 경험이 여러분에게 도움 됐으면 합니다.
무엇이 필요한가?
잡플래닛은 그간 많은 개발자의 손을 거쳤고 그렇게 설치된 라이브러리는 300여 개에 달합니다. 현직 개발자가 파악하지 못한 라이브러리들이 얽히고설켜 있었습니다. 그 때문에 새로운 라이브러리를 설치하기 어려웠고. 크게는 Ruby, Rails, Mysql 업그레이드가 불가능했습니다. 그야말로 옴짝달싹하지 못하는 상황이었습니다.

현직 개발자가 알고 있는 라이브러리들마저도 각자 머릿속에 흩어져 있었습니다. ‘퍼즐 조각’이 이곳저곳에 퍼져있는 격이죠. 이 모든 ‘퍼즐 조각’을 모을 수 있는 ‘퍼즐 판’이 필요했습니다. 전체 퍼즐이 완성된다면 제거할 수 있는 라이브러리는 무엇인지? 어떤 맥락으로 설치된 건지? 업그레이드가 필요한지? 등을 한 번에 볼 수 있게 됩니다.
저는 이 퍼즐을 완성하는 게 코어플랫폼 팀의 미션인 “안정적이고 확장 가능한 기술적 토대를 구축하는 것”의 첫걸음이라고 확신했고 그렇게 퍼즐 판 만들기를 시작했습니다.
퍼즐 판 만들기
퍼즐 판으로는 노션(Notion) 데이터베이스를 활용했습니다. 설치된 300여개의 라이브러리 중 명시적으로 설치된 라이브러리(Gemfile 기반) 145개 각각의 노션 페이지를 만들었습니다. 각 라이브러리 페이지는 아래처럼 구성했습니다.

분석에 필요한 정보들을 미리 마련해 놓았습니다.
- 라이브러리 문서 링크 : 분석하는 사람이 매번 검색하지 않고 손쉽게 라이브러리 정보의 구심점으로 들어갈 수 있도록, 라이브러리 버전까지 명시된 링크를 남겨놨습니다.
- 추가, 수정 commit 링크 : 어느 commit 에서 처음 설치됐는지, 수정됐는지 아는 것은 파악에 중요한 정보입니다. 이것을 통해서 누가 무슨 이유로 언제 설치했는지를 알 수 있습니다.
- 1차 분석 결과 : ‘어디에 의존하고 있는지’, ‘서비스 어느 영역에 쓰이고 있는지’ 등의 간단한 1차 분석 결과를 적어놨습니다.
집단지성을 발휘하려는 시점에서 한 사람이 주도권을 가지고 틀을 잡아놓는 것은 중요합니다. 만약 그러지 않고 동료들에게 “모두 자유롭게 라이브러리 정보를 모아주세요”라고 한다면, 개개인이 분석을 시작하고 몰입하기까지의 허들이 높아집니다. 그런 프로젝트는 추진력을 잃고 흐지부지되기 쉽습니다. 분석에 필요한 정보들을 마련해 놓는 것은 모두가 쉽게 몰입할 수 있는 문을 제공하는 것입니다.
만들어진 결과는 아래와 같습니다.

동료들의 참여를 요청하기에 앞서 라이브러리 분석 상태는 아래처럼 정의했습니다.

밋밋한 판에 퍼즐 조각이 놓일 점선을 그리는 과정이 끝났습니다. 이제 145 피스 짜리 퍼즐 판이 만들어졌고. 흩어져 있는 퍼즐 조각을 모아 완성할 차례입니다. 저는 당시 입사 3개월이 안 됐기 때문에 ‘퍼즐 조각’을 모으는 데는 동료 개발자들의 힘이 필요했습니다.
퍼즐 조각 모으기
라이브러리 정리의 필요성과 해결 방법을 정리하여 백엔드 팀에 발표했습니다. 반응은 뜨거웠고 적극적으로 의견을 주셨습니다. 덕분에 집단지성을 모으는 방식에도 많은 개선이 있었습니다.
각자가 들고 있던 퍼즐을 퍼즐 판에 올려놓기 시작했습니다. 누구도 가지고 있지 않는 퍼즐은 코드와 공식 문서 그리고 과거 슬랙을 탐험하며 찾아냈습니다. 퍼즐이 하나둘 모이고 완성되어 가는 즐거움이 있었습니다. 퍼즐 조각을 제공한 사람의 이름은 ‘검토자’ 열에 넣기로 했습니다. 마치 퍼즐 조각에 기여자 ‘이름’을 새기는 것과 같습니다. 그러면 퍼즐을 완성하는데 누가 얼마나 기여했는지 알 수 있습니다. 이런 특성들이 합쳐져 퍼즐은 게임(퍼즐은 게임이 맞다)처럼 느껴졌고 프로젝트에 속도가 붙었습니다.

145개 중 일부입니다. 라이브러리에 있는 댓글 개수와 ‘검토자’를 보면 긴밀하게 논의하며 분석했다는 것을 알 수 있습니다. 여기서 퍼즐 조각 하나를 들여다보겠습니다.

사용하지 않는 라이브러리는 동료들과 크로스 체크를 한 뒤 삭제 작업까지 진행했습니다.
한 달 만에 모든 라이브러리 파악이 완료됐습니다. 각자 다른 작업 일정을 소화하는 와중에 했다고 생각하면 굉장히 빠른 속도였습니다. (집단지성의 힘!)
50여 개가 제거할 수 있는 라이브러리로 확인됐습니다. 명시적으로 설치한 라이브러리(Gemfile 기준)의 개수이니, 의존성으로 인해 설치된 것까지 합하면 100개 이상을 제거할 수 있다는 말이 됩니다. 꼬인 의존성이 풀리기 시작했습니다.
이제 모든 라이브러리가 우리 손바닥 위에 올라왔습니다. 라이브러리 관리는 더 이상 막막한 영역이 아니라 개선이 가능한 희망의 대상이 되었습니다.
그 이후
이 퍼즐(노션)은 일회성이 아닙니다. 그 이후 새로 설치된 라이브러리도 등록하여 관리하고 있습니다. 이 프로젝트의 큰 수확 중 하나는 라이브러리별로 공론장이 만들어졌다는 것입니다. 라이브러리에 대한 변화, 분석, 논의는 모두 각 페이지에서 이뤄지고 누적됩니다. 이런 역할은 과거로 메시지가 사라지는 슬랙(SLACK)으로도, 코드에 변경이 있어야만 하는 커밋 메시지로도, 완료 상태가 있는 지라(JIRA) 티켓으로도 적합하지 않았습니다. 노션이 이 모든 정보의 물줄기가 모여드는 하천 역할을 했습니다.

커뮤니케이션도 유용해졌습니다. 노션 페이지 링크 하나로 라이브러리에 대한 모든 정보를 주고받을 수 있기 때문입니다.
이 프로젝트가 끝나고 1년이 흘렀습니다. 그 사이 의존성에 혈이 뚫리기 시작했고 막혀있던 작업들이 연쇄적으로 완수될 수 있었습니다. 54개의 라이브러리가 제거됐습니다. 염원하던 Ruby 와 Rails 버전업이 완료됐습니다. 뒤따라 Mysql 5.7 → 8.0 버전업이 잡플래닛의 데이터 웨어하우스 구축과 맞물려 완료됐습니다.
지금도 코어 플랫폼에서는 다음 Ruby, Rails 버전업을 진행하고 있습니다.
마치며
거대하고 복잡해 보이는 문제들도 작게 쪼개어 해결해 나가다 보면 정복이 가능하다는 것을 배웠습니다.
동일 시간에 동료들과의 협업은 횡적 협업이고, 기록을 활용하여 과거의 자신 혹은 동료와 협업하는 것은 종적 협업입니다. 이 두 개가 합쳐졌을 때는 강한 힘이 생깁니다. 누적의 힘은 셉니다. 저희 조직은 집단지성의 힘과 누적의 힘을 이해하고 활용하기 위해 노력하고 있습니다.
잡플래닛은 코어 플랫폼이라는 기술 기반 팀을 만들어 기술 부채 청산과 플랫폼 고도화를 위해 힘을 쏟고 있습니다. 더 안정적인 서비스를 제공하기 위해 노력하겠습니다. 감사합니다.
끝으로 저희 코어 플랫폼과 함께 안정적이고 확장 가능한 기술적 토대를 구축할 Software Architect 를 모시고 있습니다. 많은 지원 부탁드립니다.
Share article