2024년 이직 후 많은 업무가 연말에 업무가 몰리기도 했고 실무적으로의 성장하는 기간이 더 필요하다 생각해서 2024, 2025 회고를 한번에 작성한다.
외부적인 요인들로 JPA -> JdbcTemplate으로 전환하는 작업이 필요했다. 이 과정에서 JPA의 편리함보다 설계의 중요성을 느꼈다. 이보다 더 연차가 적었던 시절 기획에 주어진데로 설계하고 수정되면 그에 맞게 다시 공수를 들이는 과정이 반복의 연속이였는데 확장성을 고려하기 위해 DDD 관련된 문서와 책들을 찾아 읽고 시스템을 만드는 방법을 익혔다.
JPA를 걷어낸다는 건 객체지향과 멀어진다고 생각해서 오히려 잘못된 방향으로 나아가는 게 아닌가 생각했는데 JdbcTemplate나 MyBatis 에서 JPA로 변화하는 패러다임의 변화가 있었고 이 변화에 거슬러 올라가면서 각각의 장단점들을 직접 경험하면서 오히려 변화하는 과정을 경험하지 못한 나에게는 좋은 기회였다.
또한 JPA는 생산성을 위해 사용해야 하지만 성능이나 조정을 위해서는 Native Query로 변경할 줄 알아야 한다. ORM 쿼리들이 일으키는 비효율적인 쿼리들은 업무에서 빈번하게 일어나고 결국 기술 부채로 쌓이게 된다. 그래서 JPA와 JdbcTemplate 또는 MyBatis 를 병행하여 업무적으로 풀어나가는 데 있어서 필요한 기술 선택이다.
옛날에는 서버를 안정적인 운영을 위해 서버를 껏다 켜는 것을 최소화하기 위한 방법으로 (JdbcTemplate또는 MyBatis) + 프로시저 를 주로 사용했다고 한다.
RestAPI, Layered Architecture 등 이미 알고는 있지만 운영에서 보고 느끼면서 지속적으로 리팩토링하고 RequestDTO를 늘어나지않게 비즈니스 로직도 고려해보고 이를 통해 이전의 개인 프로젝트들 전체 적용을 하면서 리팩토링에 대한 숙련도도 쌓았다. 개인 프로젝트 중 JPA를 다시 리팩토링하면서 Java 레벨에서 동적쿼리나 JPQL 쿼리튜닝도 해보면서 숙련도를 많이 높였다.
추가적으로 Spring Cloud, Eureka, Gateway 등 서비스를 확장하고 끝에는 MSA와 K8s까지 머릿속으로 그려보기도하고 사이드 프로젝트로 진행했다.
요구사항이 나왔을 때 어느 정도 머릿속으로 구상이 되어 손가는 데로 많이 개발한 편이였는데 이 과정에서 항상 배포 끝 무렵, 오타로 인해 개발시간만큼 디버깅한 적이 많았다. 이제는 충분한 생각과 모든 요소를 고려한 테이블 설계, 애트리뷰트를 하나하나 추가하다 보니 이제는 거의 없어졌다고 느꼈을정도로 많이 고쳐졌다.
이전까지는 추가 요구사항에 대한 기능 구현이나 새 프로젝트를 하게 되었을때 API 구현에만 급급했다. 요구사항에 늘어남에 따라 더 큰 기능으로 만들다 보니 확장성이 부족한 설계로 테이블들은 기형적으로 변하고 관리 포인트만 늘어나 몸을 갈아 넣는 작업으로 변해가고 있었다.
요구사항에 맞춰 확장성 있는 테이블 설계로 다음에 발생할 요구사항까지 미리 대처하고 안정적인 기능 구현에 대한 개발 감각을 늘려갔고, 그것을 단순하게 구현할 우선순위를 정하는 힘을 늘렸다.
먼저 언급한 JPA 걷어내기 진행하면서 주 담당가 나로 정해졌다. 총 두 달의 시간이 있었고 그중 한 달 안으로 모든기능을 전환하는 것이엇다. 목표한 시간까지 배포를 위해 기존에 개발된 기능들을 단순 전환 작업을 한다고 말했고, 결과적으로 추가적인 유지보수에 대한 기간을 요구했다.
물론 이런 미래의 청구서는 완벽히 예측하는 건 어렵다. 작은 범위의 작업을 쪼개 시간 산정하고 불확실함 속에서도 견적을 내는 방법을 배웠다.
디버깅하면서 모든 함수를 세세하게 보기도했고, RFC들을 보면서 해당 기능들의 철학들을 공부했고, 기능들을 하나하나 뜯어보는 재미가 있었다.
프레임워크를 잘 다룬 프로젝트를 봤을때 마치 파인다이닝의 음식들과 같았다. 코드들은 그렇게 많지 않으나 아주 안정적이고 관리하기도 편하다. 무작정 손가는 데로 개발한 나의 코드들은 위생 관리 안 된 길거리 음식과 같았다. 더럽고 냄새나 보였다. 그래서 자주 그리고 여러 번 리팩토링하며 숙련도를 쌓아나갔다.
쿼리는 사람마다 스타일은 있지만 성능과 유지보수를 고려하여 만들다보면 끝은 비슷하다. 여기에 대한 전제조건이 테이블 설계 능력이다. 그래서 테이블을 많이 만들어보고 프로시저를 만드는 방향성으로 나아갔다.
프로시저 내에서 다양한 문법들(쿼리튜닝, 인덱싱, CTE, 임시 테이블, 커서 등)을 다루며 프로시저를 만들었다. 내가 만든 테이블들을 다시 돌아보고 쿼리를 다시 튜닝하고 성능 개선까지 일련의 작업을 반복하면서 어느정도 숙련도를 늘려나갔다.
올해 말, 마침내 Merge into(MySQL 에서는 INSERT … ON DUPLICATE KEY UPDATE)를 실무에서 써보게 되엇다.
완전히 대체되지 않는 기능이라 예시가 적절하지 않을 수도 있지만 예전에는 대부분 SQL을 이용하여 Job Scheduler 작업을 했다면 요즘은 Batch를 이용한다. 옛날 방법과 요즘의 방법 그리고 이 두 개를 직접 경험한 것이 지금까지 개발하면서 최고의 기회였다고 생각한다.
하지만 근 2년간 프로시저를 사용해 오면서 첫 1년은 무수히 많은 실패를 겪었다. 먼저 DBA 급 실력이 갖추어지지 않으면 장애가 발생했을 때 대처가 매우 힘들다. 나 또한 운영 중에 크고 작은 사고가 발생했지만 문제점을 찾는 게 여간 쉬운 일이 아니었다. 디버깅도 힘들고 형상관리도 안 되고 프로시저 공부를 시작하면서 봤던 지양하는 이유들과 그로 인한 모든 문제점들을 온몸으로 겪으면서 많은 좌절을 있었다.
25년도 작업 중 가장 기념비적인 일이었다. 그렇게 많은 데이터가 아니지만 이렇게 다뤄볼 기회는 주니어 개발자에겐 아주 흔하지 않을 일이라 생각한다. OLAP 작업을 하면서 소위 말하는 데이터를 말아 올리는 작업이 어떤 것인가를 볼 수 있었고 다양한 데이터들을 집계하고 정갈하게 만드는 작업을 했다.
앞서 설명한 JdbcTemplate나 MyBatis -> JPA로 변화와 개인 프로젝트에서는 Spring Cloud Netflix 중 Eureka 를 만들어봤다. Eureka를 실제로 개발하다보면 2~3시간이면 끝난다. 하지만 패러다임의 변화로 각각의 철학들을 공부하는데 많은 시간을 기울였다.
Clean Architecture
DDD Start!
애자일 데이터웨어하우스 디자인
친절한 SQL 튜닝
데이터 분석을 위한 SQL 레시피
이번 회사의 이직 전후로 나의 개발 능력은 압도적인 성장이 있었다고 생각한다. 어느 정도 개발이든 쿼리 작성이든 개개인의 방법이라던가 노하우는 저마다 다르지만 결국 비슷한 쿼리가 되는 것을 보면서 깊이 다가갔다는 생각이 들었다. 올해 2025년에는 데이터들을 많이 다루다 보니 남은 기간에는 이전에 다뤄볼까 했던 프레임워크들과 아키텍쳐를 다뤄볼까 한다.