안녕하세요. 백앤드 개발자 박철형입니다.
빅픽처 인터렉티브에 입사하여 약 3년간 레벨업지지(lvup.gg)의 백앤드 개발을 맡고 있습니다.
입사 후 약 3년간 짧은 기간이었지만 많은 서비스를 개발하였고 이를 통해 겪은 풍파를 공유드리려고 합니다.
제 첫 번째 기술 소개는 현재 운영 중인 레벨업지지의 기술 스택 변경 사례 바로 마이그레이션 시리즈입니다.
입사 후 1년 정도가 지났을 무렵 플랫폼의 기술적 한계를 통해 위기를 직면하게 되었고 이를 극복하고자 기술 스택을 변경하게 되었고 마이그레이션을 진행했습니다.
마이그레이션 시리즈는 아래 목차로 진행할 예정입니다.
[마이그레이션 시리즈]
- Javascript에서 Kotlin으로 기술 스택 변경
- MongoDB에서 Mysql 이전
- JPA
- 모듈러 모놀리식 아키텍처 (Modular Monolithic Architecture)
- 배포 시나리오와 중단 배포/무중단 배포
기술 스택을 변경하시는 분들에게 도움이 되었으면 좋겠습니다.
왜 NodeJS로 개발했는가?
제가 처음 입사했을 당시에 레벨업지지의 서버는 Node.js와 LoopBack 프레임워크로 개발 및 운영이 되고 있었습니다.
Node.js는 Chrome의 V8엔진을 이용하여 서버에서 Javascript를 동작이 가능한 플랫폼입니다.
현재도 그렇지만 당시에도 많은 서비스가 Node.js 기반으로 개발을 시작하고 있었습니다.
저도 학부생때 한참 Node.js의 매력에 빠져있을 때라 JAVA공화국에서 홀로 Node.js를 팠던 기억이 있습니다.(하지만 종착지는...)
그런데 왜 Node.js에서 JVM기반의 Kotlin으로 넘어갔을까요?
이유를 설명드리기 전에 간단히 JVM과 Kotlin에 대하여 소개드리도록 하겠습니다.
JVM이란?
JVM(Java Virtual Machine) 일명 자바 가상 머신은 Java Byte Code를 OS에 맞추어 해석해줍니다.
쉽게 설명드리자면 OS는 컴퓨터 언어 즉 기계어를 실행시킬 수 있는데 Byte Code는 기계어가 아닙니다.
JVM은 어떤 OS에서도 Byte Code를 기계어로 번역하여 실행시킬 수 있게 해주는 착한 친구입니다.
Kotlin이란?
Kotlin은 IntelliJ로 유명한 JetBrains사에서 공개한 JVM기반의 프로그래밍 언어입니다.
JAVA와 호환되고 JAVA로 작성된 코드는 Kotlin으로 대체가 가능합니다.
또한 구글 안드로이드의 공식 언어로 채택이 되었습니다.
Kotlin 공식 홈페이지에서도 확인할 수 있듯이 Kotlin은 모던한 언어입니다.
간결하며 안전하고 상호운용성이 뛰어난 언어입니다.
쉽게 생각하면 Kotlin은 업그레이드된 JAVA라고 생각하면 좋을 것 같습니다.
정말 많은 장점이 있기 때문에 자세한 건 Kotlin 공식 홈페이지를 통해 확인해보시는 걸 추천드립니다.
Kotlin Programming Language
kotlinlang.org
Kotlin의 장점
Javascript에서 Kotlin으로 변경을 하면서 많은 이점을 얻을 수 있었습니다.
1. 안전성
Kotlin은 정적 언어이기 때문에 강한 형 검사를 통해 안정성을 보장받을 수 있습니다.
Javascript는 동적 언어 이기 때문에 Kotlin과 같이 컴파일 시에 타입 체크를 하지 않고 Run Time까지 자료형이 선언되지 않습니다.
그래서 생각지 못한 Type Error를 마주치는 경우가 많았습니다.
2. 명시적
Kotlin은 명시적인 언어입니다.
인터페이스를 제공하기 때문에 코드를 유연하게 작성할 수 있어 재사용성이 높고 명시적인 타입 및 문법 덕분에 높은 가독성을 보장합니다.
덕분에 리팩토링할 경우에 부담감이 많이 줄었습니다.
3. 레퍼런스
무엇보다 JVM 계열의 언어는 많은 개발자 풀을 보유하고 있습니다.
또한 잘 정돈되고 보증된 문서들과 라이브러리가 많고 커뮤니티도 활성하 되어 있습니다.
이러한 이유로 많은 사람들이 JVM 계열 언어를 선호합니다.
Javascript 높은 생산성 덕분에 최근에는 Javascript도 만만치 않더라고요.
Node.js와 MongoDB로 개발 및 운영하면서 겪은 문제들
레벨업지지는 이스포츠 대회 플랫폼의 특성상 고객사가 원하는 대회에 맞추어 기능 개발을 해야 하는 경우가 많았습니다.
다행히 Node.js의 높은 생산성 덕분에 많은 고객사들의 니즈에 맞도록 빠르게 개발을 할 수 있었고 많은 대회들을 개최할 수 있었습니다.
그리고 대회들이 많이 열리자 자연스럽게 많은 참가자들이 참여하기 시작했습니다.
하지만 추가 기능들을 빠르게 개발하면서 Node.js + LoopBack의 조합으로는 한계가 보이기 시작했습니다.
개발 일정이 촉박한 상황에서 레퍼런스를 찾는데 큰 어려움이 있었고 큰 불부터 끄려다보니 코드가 점점 복잡해지고 관리가 힘들어지기 시작했습니다.
콜백 지옥 등 코드 가독성이 점점 좋지 않아 개발시 스트레스 및 장애가 발생하면 당황하는 일이 비일비재했습니다.
개발에서 가장 중요한 디버깅 또한 쉽지 않았죠.
엎친데 덮친격으로 레벨업지지는 MongoDB를 사용하고 있었는데 MongoDB를 나이스 하게 사용하고 있지는 못한 상황이었습니다.
Mysql처럼 Join이 있는 것도 아니고 트랜잭션 관리가 쉽지 않아 N+1이나 동시성 이슈 등이 빈번히 발생하였습니다.
LoopBack에서도 말씀드린 것처럼 짧은 일정 속에 관련 레퍼런스들을 찾아서 이슈들을 해결하는 건 결코 쉬운 일이 아녔습니다.
물론 MongoDB를 사용하면서 빠른 속도를 보장받았고 BSON을 제공하여 JSON 형태의 데이터를 다루기가 편리했습니다.
하지만 성능적으로 얻는 장점보다는 관리가 되지 않는 단점이 너무나 컸습니다.
그래서 가장 많이 사용되는 RDB 중에 Mysql으로 변경을 하게 되었습니다.
내부적으로 고민 끝에 빠른 시일 내에 기술 스택을 변경하지 않으면 서비스에 큰 문제가 발생하는 것은 시간문제라는 판단을 하였고 회사에서도 2달 정도 마이그레이션 일정을 잡아주었습니다.
하지만 오픈 디비전이라는 참가팀 1000팀 예상, 대회 기간 2달짜리 대회가 개최할 예정이라 마이그레이션과 기능 개발을 병행해야 했습니다.
하필 스위스 라운드라는 아주 생소하고 복잡한 대진방식으로 진행하기 되어 난감한 상황이었죠.
결국 기존 스택으로 오픈 디비전 대회를 진행하면서 마이그레이션을 진행하기로 했습니다.
하지만 2달은 마이그레이션과 기능 개발을 같이 진행하기에는 너무나도 짧은 기간이었습니다.
MongoDB의 데이터를 Mysql로 옮기는 작업부터 쉽지가 않았기에 빠르게 마이그레이션을 하기 위해 대한민국에서 가장 많이 사랑받고
인재 채용에 큰 문제가 없고 이미 검증받은 JVM 계열 언어로 기술 스택을 변경하기로 했습니다.
JVM 계열의 언어로 변경하면서 레거시가 발생하는 건 어쩔 수 없었지만 최대한으로 잘못된 부분들을 걷어내기로 했습니다.
이 과정에서 프론트앤드 개발자분들과 소통하는 부분이 정말 중요했습니다.
기존 API와 추가 개발되어야 할 모든 API들의 중요도와 사용성 등을 프론트앤드 개발자 분들과 의논하여 정리하였고 이밖에 마이그레이션을 진행하면서 기존에 잘 정돈 되지 않는 DTO를 정리 및 API를 RESTful하게 변경하기 위해 프론트 백앤드 개발자 모두 함께 마이그레이션전에 의논한 부분이 마이그레이션 시에 큰 도움이 되었습니다.
상세한 사례 등은 목차와 같이 시리즈로 상세히 설명해드리도록 하겠습니다.
JAVA or Kotlin???
결국 많은 분들이 경험하신 JAVA vs Kotlin의 기로에 놓이게 되었습니다.
JAVA의 경우 이미 입증된 언어이고 개발자 채용에 대한 걱정이 비교적 적은 편이었습니다.
또한 많은 커뮤니티와 Spring이라는 유명한 프레임워크가 있기 때문에 걱정할 게 없었죠.
Kotlin은 Java 경험자도 새로 공부해야 하고 아직 많이 사용하는 곳도 없고 개발자 채용이 어려울 것 같아 많은 걱정이 있었습니다.
하지만 Kotlin을 경험자들의 한번 Kotlin을 경험해보면 돌아갈 수 없다는 이야기를 들어버렸고 또 저 같은 경우는 JAVA나 Kotlin이나 모두 처음이 있었기에 신식 문물에 더 끌리기도 했습니다.
결국 만장일치로 갓틀린이 채택되었습니다.(당시엔 뭔가 신비롭기도 하고..)
제가 뽑은 Kotlin의 가장 큰 장점은 바로 코드의 간결함입니다. 특히 이 중에서 뽑자면 Null 안정성입니다.
JAVA의 경우 Null에 접근하게 되면 NullPointerExeption 일명 NPE이 발생하게 됩니다.
이럴 경우 매번 throw NullPointerException를 통해 과리 해줘야 하며 많은 스트레스를 유발하게 됩니다.
하지만 갓틀린의 경우 아래와 같이 ?(Question Mark)를 통해 Null 안정성을 보장받을 수 있습니다.
var a: String? = "레벨업지지"
a = null
println(a) // null
아래의 경우 컴파일 에러가 발생하게 됩니다.
val a: String = null
또한 안전한 호출(Safe Calls) ?. 문법을 통해 간결하게 안정성을 보장할 수 있습니다.
val a: String? = null
println(a?.length) // null
이밖에도 많은 Kotlin의 장점이 있으니 검색해보시면 좋을 것 같습니다.
하지만 갈길은 험난하다..
결국 이렇게 Kotlin을 채택하게 되었지만 Javascript로만 개발해오던 제가 Kotlin에 바로 적응하여 개발하는 것은 쉽지 않았습니다.
또 중요한 건 Kotlin이 끝이 아니었습니다.
- 트랜잭션 이슈로 인한 MongoDB -> MySql 이전
- JAVA의 꽃이라 불리는 Spring 프레임워크의 서브 프로젝트 Spring Boot
- JPA
- 등등..
마이그레이션을 위해 공부해야 할 것이 산더미였습니다.
마이그레이션이 저희에게 주어진 시간은 2달 정도 솔직히 마이그레이션을 끝까지 할 수 있을지 자신이 없었습니다.
과연 어떻게 이 험난한 여정을 끝냈는지 기대하셔도 좋을 것 같습니다.
감사합니다.
'레벨업의 테크노트' 카테고리의 다른 글
[1편] 개발 7년차에서 매니저 3년차로(개발팀 7명에서 33명이 되기까지) (0) | 2021.11.04 |
---|---|
[프론트엔드]데이터 시각화-닥지지 리더보드 개선 (2) | 2021.09.28 |
객체지향 방법론 고찰 (2) | 2021.08.10 |
[프론트엔드] Vue build time 최적화 해보기 (2) | 2021.07.12 |
[프론트엔드] 데이터 시각화-분포도 시각화 개선하기 (2) | 2021.07.08 |
댓글