2023년 회고(라기엔 역시나 두서 없는)
2024. 01. 04.
내가 2년차?
2023년이 시작한 것이 엊그제 같은데, 벌써 2024년이 되었습니다.
너무나도 빠르게 지나가버린 2023년을 간단히 회고해보고자 합니다.
최대한 커리어적인 부분을 기반으로 하여 주절주절 늘어놓아 보겠습니다.
첫 회사에서의 경험
아무래도 2023년 제 커리어에서 가장 큰 영향을 준 것은 2022년 12월 26일에 첫 회사에 입사한 것 같은데요. 회사에서의 경험을 중심으로 먼저 회고해보겠습니다.
협업
재직하는 회사 규모의 변화
첫 회사에 정규직으로 입사하기 전까지 저는 2022년 1학기에는 인턴으로, 인턴 종료 이후 1달이 지나서부터는 프리랜서로 스타트업에서 일하는 경험을 했습니다. 아무래도 회사의 규모가 작다 보니 제 권한의 범위가 컸고, 이 덕분에 작은 프로덕트였지만 리더십을 가지고 협업을 하는 것에 초점을 뒀던 것 같습니다.
이후 지금의 회사에 입사한 이후로는 회사의 규모가 커지면서 이런 협업의 관점이 많이 변함을 느꼈습니다. 각자의 분야에서 전문성을 명확히 가지고 있는 팀원들이 모여 있고, 개발의 범위와 프로젝트의 일정을 조율할 수 있는 기획자 그리고 갖추어져 있는 릴리즈 프로세스를 통해서 체계적으로 일이 진행됨을 느꼈습니다.
반대급부로 제 역할은 서버 애플리케이션을 개발하는 백엔드 개발자로 좁혀지는 것 역시 느낄 수 있었습니다. 이 부분이 처음에는 다소 생소하고 혼란스럽기도 했는데요. 처음 몇 달은 전 회사에서의 버릇이 남아 있기도 했고, 조직의 형태 자체는 동일하게 목적 조직이기에 제 R&R에 대해서 고민을 많이 했던 것 같습니다. 시간이 조금 지나서는 스스로 하고 싶은 말은 하는 백엔드 개발자라고 생각하고 업무에 임했던 것 같습니다. 보시는 회사분들이 계시지는 않겠지만, 이 자리를 빌어 매번 다소 놀라운 단어 선택으로 놀래켜드린 점 진심으로 사과드립니다.
독특한 조직, 수많은 유관 부서
2023년 제가 일한 조직은 백엔드 개발자로서 일하기엔 굉장히 독특한 조직이었다고 생각하는데요. 조직의 특성으로 인해 다양한 유관 부서와 협업해야 하는 기회가 많았습니다. 그래서 업무 시간 중 기술적인 고민을 하는 시간 못지 않게 협업을 위해 소통을 하는 시간도 많았습니다. 살면서 가장 많은 수의 슬랙 채널에 참여한 한 해가 아니었나 싶네요.
이런 독특한 특성 때문에 스스로 어떻게 소통해야 효율적인지, 아니면 유관 부서와 연동을 해야 하는 경우에는 어떻게 하는 것이 각 조직의 R&R 관점에서, 아니면 기술적인 대응 관점에서 더 옳은 방향인지 많이 고민했던 것 같습니다. 처음에는 회의에 들어가서 제가 구상한 서비스 연동에 대한 방법론을 설명하는 것이 너무 힘들었는데요, 이제는 경험이 좀 쌓였다고 구상한 방법론에 대한 의도와 당위성에 대해서 설명할 수 있는 정도는 된 것 같습니다.
또한 올 해 업무를 한 조직은 목적 조직의 형태를 띄고 있는데요. 한 조직 내에 기획자 / 데이터 분석가 / 디자이너 / 개발자들이 함께 모여있는 형태입니다. 이 덕분에 개발자로서의 관점 이외에도 다양한 관점에서 프로덕트를 바라보는 시각을 기를 수 있는 한 해 였던 것 같습니다. 특히 제가 들이는 기술적 공수가 어떤 지표로 나타나는지 빠르게 피드백 받을 수 있었는데요. 이 덕분에 과제를 선정할 때 비용 대비 임팩트라는, 전 회사에서는 뜬구름 잡는 소리라고 생각하던 개념에 대해서 몸으로 느끼고 이해할 수 있었습니다.
개발
Spring, 그리고 Kotlin
아무래도 올 해 제 개발 커리어에서 가장 크고 명확한 전환이라고 하면 언어와 프레임워크의 전환을 들 수 있을 것 같습니다. 2022년에는 주로 TypeScript 기반으로 업무를 수행했었는데요. 입사한 회사는 전면적으로 JVM 기반으로 되어 있다고 알고 있었기에 Spring으로의 프레임워크 전환은 불가피해 보였습니다. Spring과 Java 기반으로 개발을 한 경험은 있었기에 사실 크게 걱정을 하고 있지는 않았습니다. 다만 JVM 기반 생태계에서는 OOP 개념에 대한 평균 수준이 많이 높다고 알고 있고, 원체 클래스와 인터페이스를 많이 생성하는 코드 스타일에 익숙하지 않아 다소 걱정을 하기는 했습니다.
그런데 입사를 하고 나서 저희 부서는 이미 제가 입사한 시점에 모든 프로젝트를 Kotlin 으로 전환한 상태였다는 것을 알게 되었습니다. 당장 입사 하루 전 날까지 “Kotlin으로 Spring 개발을 할 수는 있는데, 되게 힙한 스택이다” 라고 알고 있던 제게는 꽤 신선한 충격이었습니다.
입사 이후 거의 일주일동안은 온보딩 시간을 제외하고는 Spring과 Kotlin 학습이 주된 업무였습니다. 다행히 Kotlin은 코드의 스타일이 TypeScript와 크게 다르지 않았고, 특유의 편의성과 간결함에 힘입어 빠르게 Kotlin 스타일에 적응할 수 있었습니다. Spring 은 제가 공부하던 시점에 Spring Framework 6과 Spring Boot 3이 릴리즈 된 시점이었는데요. 책들은 대부분 Spring Boot 2 기준으로 작성되어 있어, 책의 실습 내용을 Spring Boot 3으로 실시간 포팅해가며 학습을 했습니다. 이 과정에서 Spring Boot 3.0 Migration Guide 그리고 그 유명한 Baeldung 아티클을 보며 그 꼼꼼함과 친절함에 감탄했던 것 같습니다.
개인적으로 로직의 가시성이 떨어진다는 점 그리고 뒷단에서 일어나는 마법 같은 일이 많다는 점 때문에 Spring을 크게 좋아하지는 않았는데요, ASP.NET 과 더불어 엔터프라이즈 환경에서 사용하기 편한 프레임워크에는 그 이유가 있구나라고 느꼈습니다.
Coroutine, R2DBC 드가자~ (부제: 하루 들여서 탈출할 수 있으면…)
신규 입사자 과제를 진행하며 간단하게 Kotlin 기반으로 Spring Web (MVC) 그리고 JPA에 대해 감을 익힌 다음 실제 프로젝트에 투입되었는데요. 신규로 서버 애플리케이션을 구성하는 프로젝트였습니다. 이 과정에서 기술 스택 선택의 갈림길에 놓이게 되었는데, 같이 프로젝트 개발을 진행하신 팀원 분이 당시에 Spring WebFlux 기반에서 Kotlin Coroutines 그리고 R2DBC를 활용하여 비동기 기반의 서버를 구성해보자고 하셨습니다. 신기술 병이 있는 (아직도 중증입니다) 저였던지라 바로 고개를 144hz로 끄덕이며 동의했고, 그렇게 Spring WebFlux + Kotlin Coroutines + R2DBC 기반의 서버를 개발하게 됩니다.
Kotlin 환경에서 비동기 관련 경험이 없었던 터라 개발하는 과정이나 성능 테스트를 하면서 고생을 좀 했었는데요, 처음에는 성능이 너무 안나와서 병목의 원인 같았던 Coroutines를 걷어내고 WebFlux 기반으로 코드를 모두 재작성할까 했지만, Reactive 기반으로 작성하기엔 로직이 너무 많아서 결국 포기하게 되었습니다.
물론 이는 제 Coroutines과 Kotlin에 대한 이해도 부족으로 인한 문제였습니다. 다행히 지금은 운영 환경에서 일단은 안정적으로 잘 동작하는 상태까지는 폼을 올려두어 서비스하고 있습니다.
Hexagonal Architecture
위에서 진행한 프로젝트는 처음에 Layered Architecture 기반으로 개발했습니다. 서비스를 굉장히 빠르게 개발할 수 있었지만 출시 이후 프로젝트의 의존성이 여기저기 꼬여 있다는 생각을 했습니다.
이 부분을 개선하기 위해 여러 아티클과 예제를 스터디해가며 Hexagonal Architecture 기반으로 코드를 모조리 재작성한 후 팀원들에게 공유하고 적용했는데요. 아직도 400개 이상의 파일 변경을 보고 놀라시던 팀원 분들의 표정이 잊히지 않습니다.
매핑 로직은 많아졌지만, 도메인 로직의 순수함을 지켜낼 수 있었다는 점 그리고 연동 서비스의 응답이 달라지거나 연동 대상 서비스 자체가 변하더라도 어댑터의 로직만 변경해도 되는 점이 가장 큰 장점으로 다가왔습니다.
지금 와서 다시 보면 수정할 부분이나 개념적으로 올바르게 이해하지 못하고 작성한 코드들이 많이 보이는데요. 코드 레벨 아키텍처에서 이 정도로 깊게 고민을 하고 수정을 한 것은 처음이라 의미 있는 경험이었던 것 같습니다. 코드를 설명하며 팀원들을 설득한 것도 꽤 기분 좋은 경험이었구요.
IDC 환경을 만나다
아마 요즘 개발자의 길을 준비하시는 분들은 대부분 클라우드 환경을 기반으로 인프라를 구성하시는 경험을 할 것입니다. 저 역시도 그랬고, 주로 AWS 환경에서 Terraform 기반으로 인프라를 손쉽게 구성했었습니다.
올 해 처음으로 IDC 환경을 메인으로 업무를 했었는데요, 이 부분이 생각 외로 쉽지 않았습니다. 특히 제한적인 인프라를 효율적으로 사용하기 위한 고민을 많이 하는 습관을 들일 수 있었습니다. 예를 들어 클라우드 환경에서는 크게 신경 써본 적 없는 DB 스토리지 용량에 대해서도 신경을 써야 했습니다. 사실 상 유저 1명 당 데이터 양 * 유저 수 만큼의 데이터가 발생하기 때문에, 이런 부분을 고려해야 했습니다. 이 때문에 예전 같았으면 별 생각 없이 DB에 남겼을 로그성 유저 행동 데이터 등 여러 데이터에 대해서도 다시 바라보게 되었던 것 같습니다.
Kubernetes를 만나다
2022년에는 컨테이너 기반으로 개발을 해서 배포를 하긴 했지만, 모놀리스 형태로 서비스를 배포했기 때문에 Kubernetes에 대한 수요가 그리 크지 않았고 AWS ECS Fargate 기반으로 배포를 했었습니다. 한편으로는 그래서 Kubernetes 환경에서 일하면 백엔드 개발자로서 어떤 느낌일까 궁금하기도 했습니다. 이름도 그렇고 마크도 굉장히 멋있어 보였거든요.
실제로 와서 경험해보니 DevOps, SRE 직군분들이 K8S 환경과 배포 파이프라인을 모두 구성해두셨기 때문에 실제 백엔드 개발자는 인프라에 대해서 크게 신경쓸 일이 없긴 했지만, 그래도 노드, 파드, 서비스, 인그레스, 서비스 메시, Helm 차트 등 굉장히 새로운 부분들을 많이 배울 수 있었습니다.
전체 서비스 인프라를 지탱하기 위해서 이렇게 많은 개념들과 기술이 사용되고 있음에 새삼 놀랐고, 이런 인프라를 지탱하는 DevOps 직군에 대해서도 흥미를 느끼게 되는 경험이었습니다.
사이드 프로젝트
회사에서 하는 일 이외에도 학교 동기들과 사이드 프로젝트를 하나 진행했었는데요. 프로젝트를 길게 진행하면서 느낀 점들도 간단히 정리해보려 합니다.
흐지부지
4년의 학부생 생활을 하면서 프로젝트를 진행하면 항상 섣불리 갑갑해서 프로젝트를 리드하는 역할을 많이 했었는데요. 이런 제 성격 탓에 다른 팀원들이 프로젝트에 적극적으로 참여할 수 있는 기회를 많이 빼앗은 것이 아닌가 싶은 생각을 하곤 했습니다. 그래서 이번 프로젝트에서 제 컨셉은 기획이나 서비스 개발에 최대한 적게 참여하고, 자율적으로 프로젝트를 진행할 수 있게 인프라나 공통 Gateway 서버를 구축해주도록 하자 였습니다.
하지만 여러 한계점들이 복합적으로 작용하면서 해당 프로젝트는 흐지부지 끝나게 되었고 마지막까지 FE와 BE가 연동되어 동작하는 모습을 보지 못했습니다. 프로젝트가 이렇게 아쉽게 끝난 이유를 간단히 짚어보려고 합니다.
기획력이 크게 필요한 어려운 주제
저희의 주제는 스터디를 모집하고 진행할 수 있는 플랫폼이었습니다. 이후 해당 스터디의 내용을 기반으로 블로깅까지 지원할 수 있도록 한다는 야심찬 꿈을 세웠지요.
문제는 이런 플랫폼을 완성하기 위해선 기획력을 크게 요한다는 것이었습니다. 다들 개발자로 구성되어 있었기 때문에 기획을 이끌어 나가기에 필요한 공수가 너무나도 컸습니다. 거기다 주제 자체도 이미 존재하는 유명한 서비스가 있지도, 정형화된 형태가 있지도 않다 보니 프로덕트를 설계하는 것 자체가 쉽지 않았습니다.
적어도 유명한 서비스가 있다면 다들 “아 그런거!”라는 식으로 직관적인 유추를 해가며 공감을 하고 나아갈 수 있었을텐데, 그런 부분이 전혀 없었기에 기획도 디자인도 개발도 모두 어려웠던 것 같습니다.
루즈한 일정 관리
매 주마다 비대면으로 진척도를 체크하기는 했지만, 그 누구도 일정에 대한 압박을 하지 않았습니다. 제가 팀원들을 모을 때 한 이야기도 “부담 없이 천천히 함께 성장하는 프로젝트”라고 했었기에 일정에 대해서는 부담을 느끼지 않았으면 하는 생각도 컸습니다.
아무래도 이번 사례를 통해서 부담 없이 천천히 함께 성장하는 프로젝트라는 모델은 업무 이외에 진행하는 사이드 프로젝트에는 적용하기 어렵다 결론짓게 된 것 같습니다. 다들 퇴근 이후 힘든 상태로 추가적인 무언가를 해야 하기 때문에 큰 자기 동기가 있지 않으면 정해진 일정에 대한 관리 없이 프로젝트를 진행하는게 쉽지 않다고 생각하게 됐습니다.
높은 인프라 러닝커브
이번 프로젝트를 시작으로 이 팀에서 여러가지 서비스를 앞으로 함께 개발하겠다는 욕심을 가지고 있었습니다.
여러가지 서비스를 하나의 계정으로 사용할 수 있게 하기 위해서 통합 인증 서버를 구성하고, 여러가지 서비스에 대한 인증을 그 서버 하나에서 처리한 다음 계정의 ID를 헤더에 심어서 뒷단 서비스로 전달하도록 게이트웨이를 구성했습니다. 말로만 놓고 보면 어느 정도 자연스러운 인프라 구성이었지만, 팀원들은 TypeScript 기반으로 NestJs를 처음 스터디하며 백엔드 서버를 구성하는 입장이었기 때문에 이 부분이 높은 러닝 커브로 다가온 것 같습니다.
거기다 독선적으로 인프라와 게이트웨이 아키텍처를 구상하고 개발했기 때문에 팀원들의 공감도 크게 얻지 못한 것 같습니다. 아쉽게도 나중에는 팀원들의 일정 이슈가 겹쳐 마지막까지 게이트웨이와 서비스 서버를 연동하지 못하고 프로젝트를 마무리하게 되었습니다.
개발, 인프라
프로젝트가 아쉽게 흐지부지 끝나게 되었지만, 그래도 인프라와 제반 아키텍처를 구성하면서 새로운 기술도 많이 써보고 배울 수 있었습니다.
인프라 환경 여행기
장기 사이드 프로젝트 팀을 구상할 때 개발자라면 무릇 인프라 비용을 함께 생각하게 됩니다. 계속해서 서비스가 늘어나게 될테니 부담해야 하는 비용도 늘어날 것으로 예상해서, 그냥 저희 집에 온프렘 환경으로 작은 서버를 구성해두고 거기에 자동 배포가 가능하도록 서비스를 구성했습니다.
처음엔 서비스들을 배포하기 위해 맥 미니를 처음 구매해서 docker compose 기반으로 서비스를 배포했었습니다. 이 환경에서 배포를 수행하기 위해 GitHub Actions에서 Ansible을 활용하여 ssh 명령을 실행하는 식으로 처음 인프라를 구성했었습니다.
이후 맥 미니 한대로는 부족하겠다는 판단이 들어 미니 PC를 3대 구매했습니다. 이 PC 3대를 묶어서 Kubernetes를 구성해보려고 했습니다만, 수많은 개념 압도당해 결국 구성하지 못하고 훨씬 적용하기 쉬운 Docker Swarm 형태로 클러스터를 구성했습니다. 그리고 이 환경 위에서 Nginx로 API Gateway도 구성했고, 인증을 담당하는 인증 서버도 개발해 뒷단 서비스를 갈 때 반드시 인증 서버를 거쳐서 가도록 하는 흐름도 구성했습니다. 배포는 여전히 Ansible을 통해서 ssh 명령을 실행하는 식으로 되어 있었습니다. 결국 Kubernetes를 한번은 사용해보고 싶다는 생각에 K3S 기반으로 클러스터를 이전했고, Helm Chart나 ArgoCD 등을 적용하여 GitHub Actions 에서도 Ansible을 걷어내고 조금 더 나은 방법으로 배포 프로세스를 구성했습니다.
작고 귀엽지만 온프렘 환경에서 K8S 노드 3개를 굴려서 클러스터를 구성해보고 배포 파이프라인까지 직접 구축해보는 귀중한 경험을 한 것 같습니다.
Ktor
회사에서 Kotlin을 사용하다 보니 이 언어가 굉장히 요물로 느껴졌습니다. 그래서 Spring 이외에 활용할 수 있는 프레임워크를 찾아보다 Ktor를 만나게 되었습니다. Coroutines 기반으로 로직을 작성할 수 있는 경량 프레임워크인데, Spring이 NestJs 라면 Ktor는 express 같은 느낌이었습니다. 사이드 프로젝트에서 활용한 인증 서버도 Ktor 기반으로 구성했는데요, 로직이 투명하게 모두 드러나있단 점에서 취향에 따라 선택할 수 있는 프레임워크라는 생각이 들었습니다.
이외에도
Go로도 오랜만에 꺼내서 서버도 한번 작성해보고 했었는데요, 너무 날치기로 공부하고 로직을 작성했어서.. 아쉽습니다. 메모리 Footprint가 정말 놀랄만큼 작아서, 나중에 다시 한번 꼭 활용해보고 싶습니다.
앞으로는?
다시 주도적으로 프로젝트를 리드하는 방향으로 가보려고 합니다. 이러니저러니 느낀 점들이 많기도 했지만 그냥 제 성격이 이렇게 생겨먹은 것 같다는 생각도 드네요. 프로젝트를 잘 리드하면서, 팀원들을 존중할 수 있는 태도를 갖추는 것이 오히려 함께 윈윈할 수 있는 방향이 아닐까 싶은 생각입니다.
기술적으로는 너무 높은 러닝커브를 가져가지 않으려고 합니다. 백엔드만 놓고 보면 모놀리식 구조로 서비스를 모두 구현한 다음, 이것을 나눠야 할지, 나눈다면 어떻게 나눠야 할지 등의 부분을 논의해서 팀원들의 공감을 기반으로 프로젝트를 진행하는 것이 맞을 것 같습니다.
개인
마지막으로 개인으로서의 한 해를 돌아보려 합니다. 이 부분은 부제를 나누지 않고 간단히 해보려고 하는데요.
언제나 그렇듯이 많이 아쉬움을 느낀 것 같습니다. 해보고 싶은 프로젝트도, 하고 싶은 공부도 많았지만 계획 단계 까지도 가지 못하고 좌절된 것들이 많았던 것 같습니다.
여러 기술 서적을 구매했지만, 진짜 겉으로 훑어보기만 하고 내용이 하나도 기억나지 않는 책들도 많을 정도이니 회사나 사이드 프로젝트의 도움을 받지 않고 스스로 이뤄낸 성장이 참 모자라다는 생각이 드네요.
올 해는 공부도 그리고 메모도 많이 하고, 스스로 의미 있는 정보도 많이 습득하고 또 저만의 언어로 풀어내보는 시간을 많이 가져보고 싶습니다.
마무리
많이 배우고, 많이 아쉬웠던 2023년이었습니다.
이전 회사의 CTO 님이 개발팀 문화를 설명하는 노션에 적어두셨던, 제가 정말 좋아하는 문구가 있는데요.
3개월 전의 나와 비교했을 때 내가 지금 성장하고 있는 방향을 설명할 수 있어야 하고
6개월 전의 나와 비교했을 때 내가 지금 성장하고 있는 속도를 보여줄 수 있어야 하고
1년전의 나와 비교했을 때 내가 지금 얼만큼 성장했는지를 증명할 수 있어야 합니다.
하나라도 해당하지 않는다면 위기의식을 가져야 합니다.
어떤 방향으로 나아갈지, 어떤 속도로 성장할지, 어떤 나의 성장을 증명할 수 있을지 지금은 전혀 예측할 수 없지만 이 3개월, 6개월, 1년이 지날 때 문구를 만족할 수 있는 한 해가 되었으면 합니다.
두서 없는 넋두리 읽어주신 분들 감사합니다. 다들 새해 복 많이 받으세요!
끝.