[회고] 2021년

Karsei
|2022. 3. 27. 23:47

Spring Boot 어플리케이션을 처음으로 실무에 적용하고, 직접 장애를 겪어보고, 동시에 보람있는 경험도 같이 겪은 해였다.

 

작년에 Graylog 로 Gateway 같은 역할을 하는 서버에 요청 지표를 알 수 있도록 하는 모니터링 작업을 진행했었는데 그 지표를 잘 확인해보라는 듯이 무섭게도 작년 말, Meta 키워드 때문에 엄청난 트래픽이 몰리면서 Oracle 로 인한 사내 전체 장애가 일어났었다(기사). 이런 경우 어느 정도의 요청이 들어오는지 지표를 확인할 수 있는 경험을 겪었고, 다른 서비스들이 장애가 일어나서 작동이 안될 때 처음으로 실무에 적용한 Java Spring Boot 애플리케이션만이 유일하게 멀쩡하게 작동되는 경험까지 함께 겪게 되었다.

 

휴면 계정

회사에서 예전에 인수한 회사가 있었는데 우리 사업팀과 관련된 분야이다 보니 사내에서 따로 회원 관리를 담당으로 하는 팀이 있음에도 해당 팀에서는 DB에서 취급하는 고객 서비스 영역이 달라 해당 웹 서비스의 회원 관리를 하지 않을 거라고 전달을 했다고 한다. 그래서 이런 부분들은 우리 팀이 대부분 관리해왔다.

 

이번에 필요했던 작업 중 하나가 휴면계정 작업이었다. 휴면계정 처리는 주어진 기간 동안 서비스 이용 내역이 없으면 메일을 먼저 보내고 나중에 회원 관련 정보를 다른 곳에 미리 저장 후 중요 데이터를 제외하고 기존 정보를 전부 삭제하는 식으로 이루어졌다. 휴면계정 해제를 할 때도 기존에 저장했던 정보를 기존 레코드에 원복시켜서 진행하면 되었다. 해제할 때 본인인증을 이용한 방법과 서류 제출을 통한 방법이 있었는데 본인인증은 이메일 또는 휴대전화를 이용해서 진행하면 되었고 SMS, 이메일 전송 시스템은 사내에 이미 구축되어 있던 데다가 이를 활용한 서비스도 많아서 코드를 참고하며 어렵지 않게 진행했다.

 

판매가 계산 통합

우리 팀에서는 4개의 서비스 사이트와 API 서버 및 벡오피스 등을 추가적으로 관리하고 있다. 이런 서비스들을 관리하면서 너무 불편했던 것 중의 하나는 모든 서비스마다 가격 계산 로직이 따로 존재했다는 점이다. 즉, 가격 계산 로직에서 수정해야 하는 사항이 있다면 각 서비스마다 하나씩 분석하고, 수정하고, 커밋하고, 배포하는 작업을 반복적으로 해야 했던 것이다.

다행인 것은 전체적으로 계산 로직 프로세스는 비슷했다. 테스트 코드마저 존재하지 않아서 자주 마음속으로 어떻게 개선하면 좋을지 생각하곤 했다.

 

작년에 정책, 상품 관리 시스템을 개발하면서 기존 가격을 관리하던 DB를 다시 만들었고, 이번엔 그 테이블을 바라보도록 판매가 계산을 다시 손봐야 하는 상황이 오게 되었다. 가격과 관련된 부분은 비즈니스 관점에서 상당히 중요한 영역이라고 생각했다. 안정성과 테스트만큼은 반드시 보장되어야 한다고 생각했고, 서비스 연계 시 기존 가격과의 검증이 제일 중요하다고 판단했다. 또한, 간헐적으로 Oracle 부하로 전사 장애가 일어났기 때문에 기존에 작성된 PHP 로 작성된 코드로는 이를 해결하기 어렵다고 판단하여  DB Pool 을 이용하고자 이전부터 공부해오던 Java Spring Boot 를 이용한 API 로 새롭게 만들게 되었다.

 

신규로 작성된 가격 계산 프로세스는 크게

  1. 상품 기본 정보 및 정가 조회
  2. 팩토리 메서드 패턴을 이용한 조건별 각 가격요소(타 API 결과 조회, 할인, 고객 유형 등) 계산
  3. 위 가격요소를 조합하여 내부 정책에 따라 우선순위별로 가격 결정

순으로 진행되도록 설계했다.

 

기존 로직의 flowchart 와 신규 로직의 flowchart 를 만들어서 이사님에게 설명하고, 프로토타입으로도 만들어서 어떻게 계산할지에 대해 개발팀하고 지속적으로 같이 얘기를 나누어서 진행했다. 특히, 기존 계산 로직들이 스파게티 코드 수준으로 복잡했고, 테스트 코드도 없어서 기존 로직의 flowchart 를 그리는데 너무나도 힘들었다. 팀원분들이 어느 부분은 사용되고, 사용되지 않고를 많이 알려주셨다.

 

처음으로 Java Spring Boot 를 사용하는 프로젝트였어서 처음에 많은 트러블 슈팅이 있었다. 특히, 설계에 많은 관심이 있어서 우아한형제들의 멀티모듈 설계 이야기도 보고 그랬는데, 무슨 말인지는 대충은 알았으나 정확하게는 이해를 못했다. Gradle 을 통해 멀티모듈 설계도 해보고 그랬지만 뭔가 아닌 것 같아서 우선은 일반적인 MVC 패턴으로 짜보고 테스트 코드라도 작성을 해두고 나중에 리팩토링을 통해 개선해보기로 결정했다.

 

JPA와 QueryDsl 를 처음으로 사용해봤는데 이때 MyBatis 도 같이 고려했었다. 왜냐하면 개발팀이 SQL 작성에 익숙했고, 사내에 DBA 가 없어서 직접 복잡한 여러 서브쿼리나 함수를 많이 사용해왔기 때문에 나중에 유지보수 시 팀의 프레임워크 성숙도를 고려하여 JPA 보다는 MyBatis 가 낫지 않을까 생각했다. 그래서 같이 사용하는 형태로 처음에는 진행했었는데 나중에야 JPA 에서도 native 쿼리를 실행할 수 있다는 것을 알고는 MyBatis 는 쓰지 않기도 했다.

 

개발이 끝난 후에는 예상대로 검증이 어려웠다. 우선적으로 각 서비스에서 API 를 호출하도록 연결하는 과정에서 기존 계산 로직과 이번에 개발한 API 를 같이 호출하도록 했다. 서로 결과를 받아서 비교한 다음, 다른 부분이 있으면 모니터링으로 띄우도록 진행했다. 이 부분은 기획과 함께 가격을 어떻게 계산해야 하는지 같이 얘기하면서 진행했고 프로세스를 다듬어 나갔다. 검증을 위해 빠르게 PHP 로 주문서 가격 불일치 체크 자동프로그램까지 만들고 제대로 계산이 된 것이 맞는지 확인까지 했다. 검증이 끝난 후에는 각 서비스에서 신규 API 호출만을 하도록 바꾸었다.

 

다행히 성공적으로 프로젝트를 끝냈다. 특히, 가격 프로세스를 수정하는 부담이 매우 적어졌고, 마침(?) 작년 말에 Oracle DB 부하 때문에 전사 장애가 일어났는데 유일하게 DB Pool 을 사용한 API 였어서 혼자만 멀쩡했었다. 다른 팀원분들에게 자랑할 정도로 굉장히 많은 보람을 느꼈던 프로젝트였다.

 

멘토링

이번에 신입을 한 명 데려가야 해서 신입 수습기간 동안 동기 1명하고 같이 멘토링을 하게 되었다. 내가 팀에서는 제일 어렸고(…) 시니어 분들 중 아무도 멘토링을 하려고 하지 않아서 결국 내가 하게 되었다. 심지어 사내 팀마다 이런 신입들이 회사에서 잘 적응할 수 있도록 보조하는 제도가 멘토링과는 다르게 또 진행되었는데 멘토 선정과 같은 이유로 다른 신입을 보조하는 업무까지 함께 진행되었다.

 

멘토링을 하면서 크게 느꼈던 점은 멘토를 하고 있는 내가 너무나도 부족했다는 것이었다. 마침 PHP 말고 Java Spring Boot 어플리케이션을 실무에서 직접 활용하며 개발하고 있었는데, 내가 맡은 멘티들은 Java Spring Boot 를 가지고 개발에 참여했고 나 또한 배우는 입장이었다. 그렇기에 내가 프레임워크에 대해 어떻게 조언을 해줄 수가 없었는데 같이 멘토링을 담당한 동기 1명이 다행히도 Spring Boot 를 가지고 개발했던 적이 많아서 프레임워크와 관련된 부분을 동기가 크게 활약했다. 하지만 지금까지 내가 실무에서 무엇을 하면서 성장하고 있었는가에 대해 다시 한 번 생각을 하면서 회의감을 강하게 느꼈고, 앞으로 많은 공부를 해야 겠다라고 크게 다짐하는 계기가 되었다.

 

로그 수집 분리

이때는 Graylog 로 먼저 쌓도록 진행했었다. 해당 글로 다시 재작성해서 갈음하였다.