nGrinder는 2012년에 완전히 처음부터 재개발 시작하면서 새롭게 기술 스택을 정의하여야 했습니다. 대충 알고 계실지 모르겠지만, nGrinder 는 현재 성남에서 근무하는 한국인 리더 1명, 북경에서 개발하는 중국인 개발자 3명(QA1명 추가)이 같이 개발하였습니다. 이렇게 먼 거리에서 개발을 해야 했기 때문에, 서로 기술 정보를 공유해가며 개발하기가 힘들었습니다. 처음에는 RAD를 지원하는 Play 나 Grails 같은 것으로 개발하는 것이 좋을 것 같았습니다. 그러나 제가 처음 이 말을 중국 개발자들에게 꺼내었을 때, 중국 개발자 표정이 갑자기 변하는 것을 급히 맘을 접었습니다. 개발자가 바로 옆에 있으면 그들이 익숙치 않은 기술에 대해 조곤 조곤 설명해 줘 가면서 끝까지 가보겠는데, 원격에서 일하는 개발자에게 그런 것을 요구하는 것은 거의 재앙에 가까울 수 있었기 때문입니다.
nGrinder와 스프링
그래서 nGrinder 3.X 은 nGrinder 2.X 의 기술 스택이었던 스프링/Freemarker로 재 개발하기로 결정합니다. 그런데 혹시 스프링으로 구현된 설치형 소프트웨어를 보신적 있나요? 설치형오픈 소스 프로젝트 중 자바로 개발된 것중 유명한 Jira나 Jenkins 를 살펴보면 내부 코드를 살펴보면 내부에 스프링이 들어가 있다는 사실을 알 수 있긴 합니다만, 보통 이런 도구들은 Spring을 의존성 주입 용도로만 사용합니다. 웹 단이나 데이터 단의 프레임웍으로는 보통 다른 것을 사용합니다. Jenkins 는 웹 단을 Stapler 라는 자체 MVC 프레임워크를 사용하고, Jira 도 뭔가 이상한 것(아직 파악 못했습니다.)을 사용합니다. DB도 완전히 Spring JDBC나 Spring Data가 아닌 Ofbiz Entity Framework을 사용하구요. 어떻게 하면 스프링을 좀 더 오픈소스에 적합한 형태로 사용할 것인가가 고민거리도 다가왔습니다.
두 개의 소스 트리
과거 버전인 nGrinder 2.X 는 사실 그다지 성공적인 제품이 아니었습니다. 몇 가지 이유가 있었는데, 그 중 하나는 NHN 내부용 버전과 github에 공개되는 버전이 따로 개발되고 있었다는 것 입니다. NHN에서 사용하는 SSO 처리와 사원 DB 동기화 로직이 코드에 박혀 있었는데, 당연히 이를 github 에 공개할 수 없었습니다. 따라서 주기적으로 이런 부분을 제거한 다음에 github에 커밋할 수 밖에 없었습니다. 따라서 두 개의 다른 팩키지 수준이 아니라 서로 다른 소스 트리를 유지해야만 했습니다. 보통 이런 상황에서 개발자는 두 개 소스 트리에 모두 적절한 변경을 가하길 힘들 겁니다. 보통은 둘 중에 윗 선에서 관심을 두는 브랜치에 대해서만 개선을 진행하게 됩니다.
이에 따라 당연히 외부 오픈 버전은 관심 대상에서 멀어지게 되었습니다. 개발자는 바로 옆에서 피드백을 받을 수 있는 NHN 내부 버전에 집중하게 되었고, 따라서 결국 한동안 외부 버전이 업데이트 되지 않았습니다. 사실 이와 같은 현상은 특정 회사에서 주도하는 대다수의 오픈 소스 프로젝트에서 발생될 겁니다. 따라서 어떻게 하면 코드 트리를 하나로 유지하면서 사내와 사외 버전의 요구사항을 모두 반영할 것인가가 중요 이슈가 되었습니다.
큐브리드!
nGrinder 2.X 이 가진 또 하나의 기술적인 문제는 데이터 베이스였습니다. nGrinder 2.X는 NHN이 자체 개발한 데이터베이스인 큐브리드를 사용하였습니다. 큐브리드는 낮은 인지도에 비해 정말 좋은 데이터베이스 입니다. SQL 구문이 MySQL과 거의 대부분 호환되기도 하고, GUI 기반의 관리툴을 제공합니다. 그리고 오픈소스 도구 중에 유일하게 HA를 를 무료로 제공합니다.
그러나 큐브리드는 사용 기반이 별로 탄탄하지 않습니다. nGrinder 2.X 설치시에 사용자들이 익숙하지 않은 데이터베이스를 강요하다 보니, 여기서 nGrinder 적용을 포기하는 경우가 생겼습니다. 사용자는 설치를 위해 몇 십 페이지짜리 메뉴얼을 읽지는 않을 겁니다. 반 페이지 정도가 아마도 사용자에게 강요할 수 있는 최대 설치 가이드 한계일 겁니다.
그래서 처음에는 데이터베이스 레이어를 완전히 다른 것으로 대치하는 것을 고려하게 됩니다. 그러나 저희 센터장님이 한말씀을 하셨습니다. “nGrinder 사용량이 늘어나면 큐브리드 인지도도 늘어날 것으로 기대한다.” NHN에서 큐브리드는 연간 50억 이상을 투입 할만큼 중요한 위치를 차지하고 있습니다. 이러한 상황을 고려하자면, 큐브리드는 절대 버릴 수 없는 하부 시스템입니다. 방법은 다수개의 데이터베이스를 동시에 지원하는 것을 원칙으로 삼게 되었습니다.
그러나 다수개의 데이버테이스를 모두 테스트 해 볼만큼 개발 리소스가 충분하지 않았습니다. 어떻게든 Free Lunch 를 먹어야만 했습니다. 다행이도 저는 예전에 여러 데이버테이스를 지원하는 OR맵퍼인 하이버네이트를 잠시 써본 경험이 있었습니다. iBatis 같은 SQL 중심의 도구를 주로 사용한 사람들은 하이버네이트가 뱉어내는 SQL를 도대체 이해하기 힘들 겁니다. ManyToOne 이나 OneToMany 같은 조인 구문을 사용하는 순간 극도로 비효율적으로 보이는 쿼리문들이 만들어지게 됩니다. 앞서 말했던 중국 개발자들은 iBatis 에 익숙했던 친구들이라 어떻게 하면 이러한 OR맵퍼 도입을 부드럽게 진행할 것인가가 중요해졌습니다.
다음 번 포스트에는 여기서 기술한 기술적 난제를 어떻게 해결하였느냐를 기술하도록 하겠습니다.



