May 11, 2020

8년 간의 개발자 생활 회고 (2)

RIDI (2016. 6 ~ 2018. 3)

신입과 경력의 차이

두 번째 회사에서의 생활은 내게 굉장히 큰 변화였다. 일단 맥북을 쓰게 되었다. 그 전까지는 윈도우 환경에서 개발을 했고 맥북은 써본 일이 없었다. 그래서 일단 맥 사용법을 익히는 일부터 해야 했다. 뿐만 아니라 모든 것이 새로웠다. 첫 회사에서는 SVN 으로 소스 관리를 해왔기 때문에 Git 을 처음 사용해보게 되었고, 언어도 생경하기 짝이없는 PHPJavascript 를 사용했다. 특히나 PHP 는 아예 처음이었기 때문에 문법과 Laravel 프레임워크, Doctrine ORM 사용법을 익히는 데에 일주일 정도의 시간을 사용했다. 게다가 Asana 라는 생경한 툴로 태스크 관리를 했고 슬랙도 여기서 처음 써보게 되었다.

하지만 무엇보다 큰 변화는 첫 경력직으로서의 직장이라는 부분이었다. 신입과 경력의 차이는 크다. 전 직장에서는 처음부터 신입으로 입사했기 때문에 모르는 것을 모른다고 말하고 모두의 도움을 부담없이 받으며 소프트랜딩 할 수 있었다. 하지만 경력으로 들어온 이상 이젠 모르는 것을 모른다고 하기가 힘들어졌다. 모르는 것도 어떻게든 답을 내야하는 연차였다.

새로운 언어와 프레임워크를 익히고 백오피스 위주로 소스코드에 손을 대고 있을 쯔음이었다. 입사한지 약 한달 정도가 지난 시점으로 기억한다. 팀장님이 나와의 면담을 요청했다. 내용인 즉 회사에서 신규 서비스를 계획 중이고 그를 위한 새로운 팀을 빌딩중인데 여기에 참여해 주었으면 한다는 내용이었다. 나는 고민할 것도 없이 수락하였다. 일단 이미 만들어져있는 시스템을 조금씩 뜯어고치는 것 보다는 새로운 시스템을 맨땅에서부터 쌓아올리면서 배우는 것이 더 많을 거라고 생각했고, 그에 따른 기술 셋을 온전히 팀 멤버들끼리 선택할 수 있다는 것도 장점으로 다가왔다. 그렇게 나는 리디스토리 개발팀으로 이동을 하게 되었다.

신규 서비스 개발

팀 멤버는 딱 2명이었다. 추가 인원을 채용 중에 있긴 했지만 이제 막 이력서를 받는 단계였기 때문에 일단 기존 개발팀들에서 이동한 인원으로 팀을 꾸렸다. 기획이 전부 픽스되지도 않은 시기였지만 빠른 시장 선점을 필요로 하는 상황 탓에 스케쥴은 녹록치 않았다. 팀 빌딩이 8월 정도였는데 그해 말까지 Android, iOS 를 대상으로 앱을 출시해야 했다. 덕분에 우리는 픽스되지 않은 기획을 추측해가며 백엔드부터 쌓기 시작했다. 팀 인원이 둘 밖에 없었기 때문에 각자 담당 업무를 나누고 말고 할 것도 없이 서로가 할 수 있는 최대치를 했다.

백엔드 언어 및 프레임워크로는 Python + Django, Ruby on Rails, Java + Spring Boot 이 세 가지 선택지를 놓고 일주일 정도를 고민해였다. Ruby on Rails 는 개발자 수급 문제를 제쳐놓더라도 해당 프레임워크의 에코시스템 자체가 다른 프레임워크 대비 활성화되지 않아서 오래 보지않았다. 개인적으로는 아무래도 Java + Spring 쪽이 욕심이 나기는 했다. Spring 경험을 현업에서 해보고 싶기도 했고, Spring 경험이 있는 개발자를 빠르게 수급할 수 있으리라는 생각이었다. 하지만 결국 최종 선택지는 Python + Django 가 되었다. 세 가지 선택지 모두 경험이 없는 상태에서 그나마 Python + Django 의 러닝커브가 적다고 판단되었던 것이 첫 번째 이유고, Admin 툴이 기본으로 제공된다는 것이 두 번째 이유였다. 시간과 인력이 적은 상태에서 별도의 백오피스를 만들기 보다는 Django admin 을 최대한 이용하는 것이 바람직하다는 판단이었다. 이 판단은 지금에서도 유효하다고 생각한다.

인프라는 AWS 에서 제공하는 서비스를 적극적으로 이용했다. EC2, RDS, Elasticache, CloudFront, S3, CloudWatch 정도를 주로 썼었던 것 같다. 다만 일반적인 웹 서비스에서 사용되는 인프라에 대한 지식이 약했던 나 대신 팀장님이 대부분의 의사결정을 내렸고, 나는 거기에 서포트로 다양한 AWS 서비스들을 셋업하는 역할을 했다. 이 때 배포 및 프로비져닝 용도로 Ansible 을 꽤 유용하게 사용했던 기억이 있다. 소스 레포지터리는 사내에 구성되어 있던 설치형 GitLab 을 사용했고 추후에 CI 용도로 GItLab CI 를 얕게 만져보기도 하였다.

그 쯤해서 채용공고를 올려놓고 면접을 여러 번 봤다. 사실 이런 상황이 아니었다면 경력이 짧았던 내가 면접관 경험을 해보기는 어려었을 것이다. 하지만 애초에 팀원이 둘 밖에 없었기 때문에 매 면접 때마다 면접관으로 들어갔다. 다양한 경험과 뛰어난 역량을 가진 분들이 많이 지원을 해주셨고, 우리는 가능한 우리 기술셋에 대한 경험을 가지고 계신 분들을 뽑으려고 했다. 일정이 녹록치 않았던 탓이었다.

매번 지원자 입장에서 면접 자리에 앉다가 면접관 경험을 해보니 전에는 보이지 않았던 것들이 보이기 시작했다. 무엇보다 지원자가 후에 RIDI 라는 회사를 떠올릴 때 지금 내가 하는 질문이나 행동, 지원자를 대하는 매너를 먼저 떠올리겠구나, 그것이 우리 회사를 대표하는 이미지가 되겠구나 라는 생각이 들었고, 이 자리가 더욱 무거운 자리로 느껴졌다. 또한 면접 전에 이력서를 최대한 꼼꼼히 보고 필요한 질문들을 미리 가능한 철저하게 정리해놓는 편이 지원자의 합불 여부를 판단하는 데 더 도움이 된다는 사실을 깨달았다. 그렇게 여러 번의 면접 끝에 두 분의 개발자를 더 모실 수 있었다.

프론트엔드 개발

당시 리디스토리 앱은 웹 앱 형태로 만들고 있었다. 프론트엔드는 Jinja2 이라는 Template 을 이용한 전통적인(?) 방법을 썼다. SPA 가 아니니 당연히 페이지 이동 시마다 흰 공백이 노출될 수 밖에 없었고 이는 사용성을 크게 저하시켰다. 한창 서비스를 구현해나가면서도 이 부분이 계속해서 신경이 쓰였고, 이런 저런 계기로 우리는 프론트엔드 단을 갈아엎기로 했다. 지금와서 네이티브 애플리케이션으로 가는 것은 당연히 무리였기 때문에 우리는 SPA 로 가야 한다는 데에 의견을 모았고 React 를 사용하기로 했다.

위에서도 언급했듯이 React 는 독학으로 배워본 적은 있었다. 하지만 본업이 프론트엔드 개발자도 아니고, 현업에서 사용한 바도 없으니 기술적 깊이는 당연히 얕았다. 그럼에도 팀 내에 React 경험자는 나 하나 밖에 없었다. 어쩔 수 없이 선발대로 나서야 했다. 기존 Template 베이스의 페이지들을 React 로 포팅하는 데 있어서 나름의 베스트 프랙티스를 만들고, 이를 팀원들에게 전파하는 역할을 맡았다. 다행히 다른 팀원들 역시 Javascript 에는 도가 튼 분들이어서 React 포팅 작업은 생각보다 빠르게 진행될 수 있었다.

서비스 오픈

서비스는 당초 예정보다 조금 딜레이된 다음해 초에 런칭하였다. 기존 리디북스의 두터운 사용자 층이 있다보니 오픈 초기부터 꽤 많은 사용자들을 맞을 수 있었다. 오픈 전날, 밤을 새며 못다한 준비를 끝마치고 당일 아침 9시에 서비스를 오픈하자 사람들이 몰려들기 시작했다. 밤새 한 숨도 자지 못한 상태였지만 혹시나 예상하지 못한 포인트에서 장애가 발생할까봐 오전 내내 모니터링 대시보드와 데이터베이스에서 눈을 뗄 수가 없었다. 다행히 큰 장애 없이 첫 날을 넘길 수 있었다.

하지만 서비스를 운영하면서 장애를 피해갈 수는 없었다. 특히 서비스 초창기에는 장애가 종종 발생했었다. 장애에 대응할 수 있는 인원이 충분치 못했기 때문에 별도의 대응 조직이나 온 콜 스케쥴을 정하기도 힘들었다. 야밤에 아내와 산책을 나갈 때도 항상 옆구리에는 맥북을 상시로 휴대하고 다니며 슬랙에 온 촉각을 기울이곤 했다.

그러다 설 연휴가 다가왔다. 긴 연휴 기간 동안 모두가 장애 대응를 하기에는 정신적으로 스트레스가 너무 크다는 이야기가 나왔다. 그래서 연휴를 반으로 나눠서 앞 쪽은 팀장님이, 뒤쪽은 내가 메인으로 대응하기로 했다. 편안한 연휴를 보내기 위해 최대한 준비를 하기는 했지만 혹시나 하는 걱정은 현실이 되고 말았다. 당시 팀장님은 차례를 지내다 말고 날아온 슬랙 알림에 구석 자리에서 노트북을 켜고 장애 대응을 하기도 했다.

사용자가 늘어나고, 서비스 사용 기록들이 쌓이면서 기획 파트에서는 데이터베이스에 쌓여있는 사용자들의 데이터들을 유용하게 이용하려고 했다. 다행히 다들 쿼리 문법에 대해서는 능숙했기 때문에 쿼리에 대한 가이드를 제공한다던가 하는 일은 없었지만 너무 능숙해서 였을까 꽤 무거운 쿼리들이 들어오고는 했다. 당연히 쿼리는 실 서비스 DB 상에서 돌아갔고 나중에는 모니터링 차트 상에서 분석용 쿼리가 돌 때마다 리소스 사용량이 치솟고는 했다. 이에 우리는 분석용 쿼리를 던질 데이터베이스를 분리해야 한다는 결론에 도달하였다. 문제는 데이터 자체가 추후 샤딩을 고려하여 별도의 데이터베이스로 구성되어 있다는 점이었다. 기획팀에서는 분리되어 있는 데이터들에 대해 JOIN 을 걸기를 원했다. 이에 대해 처음에는 Federated Engine 을 사용해서 분리된 데이터베이스들을 하나에 모으는 방향을 구성했었다. 하지만 Federated Engine 특성상 쿼리에 대한 부하가 그대로 실 디비에 영향을 받기 때문에 운영 데이터베이스의 부하를 줄일 수는 없었다. 이에 방향을 돌려서 분석용 쿼리 전용 Slave 노드를 분리하고 이 노드가 분리되어 있는 각각의 실 데이터베이스로부터 Replication 을 받는 형태를 구상하였다. 문제는 MySQL Replication 은 single master -> multi slave 형태가 기본 구성이라는 것이었다. 다행히 MySQL 5.7 버전 버전부터 Multi Source Replication 기능을 제공했다. 하지만 RDS 에서는 이 기능을 직접 지원하지 않는다는 게 문제였다. 콘솔에서 설정이 불가능했을 뿐만 더러 Replication 설정을 위해 필요한 Super Privileges 자체를 사용자에게 주지 않았다. 따라서 RDS 대신 EC2에 직접 MySQL 을 설치하고 수동으로 Multi Source Replication 구성을 해야 했다. 사실 장애가 나도 실 서비스에 영향을 주는 인스턴스가 아니었기 때문에 굳이 비싼 돈 주고 RDS 인스턴스를 사용하는 것 보다 나은 선택지이기도 했다.

스터디

리디스토리 팀에 있는 동안은 스터디를 참 많이 했었다. 팀 멤버 분들이 전부 새로운 기술을 공부하고 이를 업무에 적용시키는 것을 좋아하는 성향을 가지고 있었다. 우리 팀 뿐만 아니라 RIDI 회사 전체에 이러한 스터디 문화가 자리 잡고 있었다. 신규 입사자는 신입 / 경력을 가리지 않고 모두 Clean Code 스터디를 해야 하는 룰도 있었고, 이후에도 공부해보고 싶은 기술이 있으면 개발센터 내에서 관심있는 사람들을 모아서 같이 스터디를 구성하는 게 자연스러운 문화였다. 그렇게 스터디를 한 주제가 TDD, DDD, Spring + Kotlin 등이 있었다. 특히 DDD 는 워낙에 개념이 어려워 한 번 스터디를 마치고도 다른 책을 구해서 심화 스터디를 한 번 더 했었다.

Spring + Kotlin 은 단순히 관심이 가서 한 스터디라기 보다는 기존 Python + Django 로 이루어져있는 백엔드에 대한 대안으로 살펴보자는 측면이 강했다. Python + Django 의 높은 생산성 덕분에 빠르게 서비스를 런칭할 수는 있었지만 점차 서비스가 커져가면서 한계에 많이 부딪히게 되었기 때문이다. 특히 Django 프레임워크 특성상 DDD 를 적용하기도 쉽지 않았을 뿐더러 어느 시점에는 프레임워크 코드 깊숙히 들여다보면서 마개조의 길을 걸어야 하는 순간들도 종종 있었다. 그런 탓에 Django 버전업을 해야 할 때마다 골치가 아팠다.

Spring + Kotlin 스터디가 끝난 후 이를 업무에 도입할 것인가를 판단하기 위해 일주일 정도 프로토타이핑을 해보기로 했다. video shop 시스템 구현을 주제로 잡았던 것으로 기억한다. 프로토타이핑 회고 결과가 정확히 기억나지는 않지만 결국 도입은 하지 않기로 하였다. 분명 욕심나는 프레임워크와 언어 이기는 했지만 당시가 Kotiln 이 백엔드에 사용되기 시작한 초창기라 레퍼런스가 많이 없기도 했고 포팅하는 리소스 대비 얻는 실익이 그리 크지 않다는 것이 그 이유였다.

서비스 종료와 새로운 시작

그렇게 서비스를 오픈하고 10개월 쯤 되었을 때 우리는 끝내 서비스 종료라는 안타까운 소식을 사용자에게 전하게 되었다. 서비스의 방향과 존속 여부에 대해 대표님을 비롯한 C 레벨에서 꽤 오랜 기간 고민을 하고 계셨고, 추석 연휴 직전에 서비스를 종료하는 쪽으로 결정이 되었다고 했다. 그 소식은 연휴가 끝난 후에 팀원들에게 전달되었다. 그동안 애착을 가지고 열심히 서비스를 개발 / 운영해온 팀원들이 가질 실망과 허탈함을 조금이라도 달래고자 대표님은 직접 팀원들을 불러모아 서비스 종료에 다다르게 된 과정을 상세히 공유해주었다. 이와 함께 우리 팀이 앞으로 다른 롤을 맡아주기를 원하며 아직 연봉 협상을 하기 전인 팀원들의 경우에는 이 서비스 종료가 연봉 협상에 절대로 영향이 없을 것이라고 이야기를 해주시기도 했다. (RIDI는 특이하게 모든 직원이 매 입사일을 기준으로 연봉 협상을 한다.)

그후 우리 팀은 계정 팀으로 이름을 바꾸고 새로운 서비스를 기획하기 시작했다. 당시 서점팀이 들고 있던 구매목록 기능을 우리 팀으로 가져오고, 장기적으로 계정 관련된 다른 기능들을 더 디벨롭하는 것으로 계획되었다. 특히 구매목록 기능은 현재의 기능을 그대로 가져오는 것이 아니라 새롭게 기획할 예정이었기 때문에 이 기능 설계에만 꽤 오랜 시간을 썼었다.

퇴사 결정

당시 나는 기존 서비스의 종료와 함께 새로운 서비스 설계에 투입될 즈음 번아웃 비슷한 상태가 되었던 것 같다. 애착을 가지고 있던 서비스를 손에서 놓는 것이 아쉽기도 했고, 당분간 길게 쉬고 싶다는 생각도 들었다. 그리고 이직에 대한 생각도 이쯤부터 하기 시작했다. 이직을 고민하게 된 구체적인 계기는 이렇다. 개발자들은 연차와 경험이 쌓이면서 도메인 개발자와 기술 개발자 둘 중 하나의 길을 걷게 되기 마련이고 당시 나는 리디스토리를 개발하면서 도메인 개발자의 길을 걷고 있었다고 생각했다. 기술적인 이슈를 딥하게 파서 답을 내기 보다는 현실세계의 도메인 문제를 어떻게 기술영역에서 풀어낼 것인가가 더 중요한 포인트였고, 이 분야가 내게 잘 맞는지에 대해 오랜 시간 고민을 해왔다. 이전 회사에서 해왔던 좀 더 기술 베이스의 일들이 다소 그립기도 했다. 물론 RIDI 에서도 좋은 코드를 고민하고, 서비스를 직접 쌓아올리면서 새로운 기술들을 공격적으로 도입하고, 훌륭한 동료들과 함께 일하는 즐거움을 충분히 느끼긴 했지만, 그럼에도 불구하고 개인적인 갈증이 해소되지 않는 부분이 있었다. 내 커리어에 대해 좀 더 진지하게 고민하기 시작하던 즈음, 나는 퇴직을 결심했다.

새롭게 옮겨갈 회사를 정해놓지 않고 저지른 퇴직이었다. 사실 일반적으로 옮길 곳을 먼저 정해놓고 퇴직을 하는게 순서겠지만 당시 나는 새로운 일을 하고 싶다는 생각 보다는 일단은 쉬고 싶다는 생각이 강했다. 직장 생활을 6년 쯤 하니까 내게도 안식월처럼 편하게 쉴 수 있는 기간이 필요하다는 생각을 했다. 그렇게 RIDI 를 퇴직하고 4개월을 내리 쉬었다. 쉬는 동안은 정말 편하게 하고 싶은 일들을 하며 지냈던 것 같다. 관심있는 분야를 공부하기 위해 도서관에 출퇴근 도장을 찍기도 하고, 아내와 차를 몰고 전국을 한 바퀴 돌기도 했다. 용돈벌이 삼아 아는 형과 함께 대리운전을 해보기도 했고, 낚시라는 새로운 취미에 재미를 붙이기도 했다. 그렇게 심신을 충분히 쉬고 난 후 나는 다시 직장생활로 돌아올 시기가 왔다는 생각을 했다.

다시 직장으로

새로운 회사를 고르는 일은 신중했다. 먼저 회사 이름보다도 Job Description 를 중점적으로 봤다. 앞으로의 내 커리어에 있어 도움이 될 수 있는 일인지, 내가 재미있게 도전할 수 있는 일인지를 판단하려고 노력했다. 그리고 단순한 웹 개발이나 도메인이 중점이 되는 공고들은 최대한 배제하려고 했다. 그러다보니 눈에 들어오는 공고들은 매우 적었다. 그렇게 고르고 고른 채용공고 중 하나가 지금 다니고 있는 SK C&C 의 공고였다. 클라우드 관련된 모니터링 서비스를 만드는 일이었고 내가 원하던 공고의 모습과 어느정도 맞아떨어졌다. 공고를 보고 지원을 했고 운좋게 합격하여 지금까지 이 일을 하고 있다.