약 8개월(2023. 08. ~ 2024. 03.)동안 진행했던 NHN 아카데미를 신청한 이유인 프로젝트를 진행하면서 어떤 과정을 겪었고, 되돌아보며 어떻게 앞으로 나아가야 할지 방향을 잡아보고자 작성합니다.
개발을 진행한 과정은 아래의 링크에서 확인해주세요 :)
- Github : https://github.com/nhnacademy-be4-ckin
- Web : https://ckin.store
치킨같은 체크인..
학교 수업을 통해 팀 프로젝트 경험이 있었지만, 인증 과정처럼 정말 철저한 계획을 바탕으로 진행한 프로젝트는 처음이었습니다. 프로젝트를 경험하기 위해서 NHN Academy를 시작한 것이기도 하였기 때문에 정말 인증 과정을 들어오기 위해 열심히 했던 것 같아요. (공로상이랑 개근상까지 받을 만큼 ^___^)
팀 프로젝트는 본 과정에서 학습했던 Java, DB, Spring Framework를 활용하고 클라우드 서비스(NHN Cloud)를 활용한 온라인 도서 쇼핑몰을 만들고 배포까지 진행하는 것을 목표로 하였습니다.
팀 프로젝트를 진행하면서 Github Organization을 활용하였습니다 :)
전공 과목에서만 듣던 스크럼 방식을 통해 프로젝트를 진행하였습니다. 문제가 발생하면 팀원들과 빠르게 소통하여 문제를 해결하는 방식이 가장 마음에 들었어요! 매 주 스크럼 마스터를 변경하여 모두가 책임자의 역할을 맡아보는 기회가 되기도 하였습니다.
매일 자신이 맡은 진행 예정 사항과 특이사항을 정리하여 체계적인 프로젝트를 진행할 수 있었습니다.
일정 관리는 로드맵, 칸반을 통해 팀원들의 진행 상황을 공유하고, 맡은 일을 한 번에 보기 쉽게 관리하였습니다. 지연되는 일정이 있다면, 팀원들이 서로 도와가며 함께 한정된 시간 내에 최상의 효율을 낼 수 있었다고 생각합니다.
담당했던 주요 내용은 다음과 같아요.
특히, 주문/결제 파트는 DB에서의 트랜잭션 처리에 대해 고민해야 될 것이 많다고 생각해서 상당히 매력적으로 느껴졌습니다. 또한 Toss Payments API를 사용할 수 있는 기회기도 했어서 담당을 하게 되었습니다.
(Toss Payments 오타 수정으로 Contributor 된 것은 안비밀 ㅎ)
관련 PR : Toss Payments API 연동 | Toss Payments API 결제
처음으로 외부 API를 사용하는 것이기도 했고, 아무래도 결제 라는 시스템적으로 문제가 발생하면 큰 문제가 발생할 수 있다고 생각하여 개발을 진행하면서 정말 고민을 많이 했던 것 같아요.
특히, 프로젝트 요구사항으로 있었던 회원 등급에 따라 결제 금액의 등급별 퍼센트 적립
을 하나의 트랜잭션으로 묶어버렸을 경우에 대해 계속해서 고민을 하였습니다. 결제 완료와 포인트 적립이 하나의 트랜잭션으로 묶이게 된다면 포인트 적립에서 문제가 발생해도 결제가 되지 않는 문제가 발생하게 됩니다.
이러한 문제를 해결하기 위해 팀원들과 의논한 결과 @Transactional의 전파(propagation) 옵션을 통해 개별 트랜잭션으로 처리하며 문제를 해결하였습니다.
Discussion : 결제 완료시 포인트 적립 처리 방법
함께 해결 방안을 찾아가는 경험은 팀 프로젝트가 아니면 할 수 없다. 혼자 해결하기 어려운 문제를 함께 찾아보며 결론을 도달하고 이를 공유하는 과정이 프로젝트 진행 과정 중에 가장 재미있는 부분이 아닐까?
DB가 분리되어 있지 않기 때문에 완벽한 MSA 환경은 아니지만, 프로젝트에서 Spring Cloud Gateway와 API 서버 스케일 아웃을 진행하였기 때문에 서비스가 커져 수 많은 인스턴스의 IP와 포트번호를 관리해야되는 상황을 대비하기 위해 Spring Cloud Netflix Eureka
를 도입하게 되었다.
이를 도입함에 따라 현재 프로젝트에서 Spring Cloud Eureka, Spring Cloud Gateway를 사용하고 있으며, 배포 환경에서는 Docker, Github Actions/Jenkins가 적용되어 있기 때문에 이러한 특징들을 활용하여 무중단 배포를 구성하였습니다.
API Server를 기준으로 설명합니다.
- API 서버는 2개의 인스턴스로 스케일 아웃 되어있다.
- Spring Cloud Gateway에서 로드 밸런싱을 통해 서비스 분산
위에서 언급한 시간을 고려하지 않고 진행하였을 때 Eureka Client가 Down이 되면 바로 Eureka Server가 요청을 보내지 않을 것이라고 생각하였습니다. 하지만, 자신의 상태를 Heartbeat를 30초마다 보내기 때문에 해당 시간을 고려하지 않아 ConnectionException 발생하는 문제점이 있습니다.
이를 해결하기 위해 server.shutdown=graceful
옵션을 통해 처리하고 있는 작업이 있다면 완료된 후 작업을 종료하게 하였으며 (최대 30s), shell script를 통해 docker가 spring boot를 잘 배포하였는지 파악한 후 다음 인스턴스 업데이트를 진행하는 방식으로 안정적인 인프라를 구축할 수 있었습니다.
목표했던 테스트 커버리지도 80% 이상을 달성하며 견고한 코드를 작성했다고 생각합니다.
2달이라는 짧은 시간 동안 대다수의 요구사항을 충족했지만, 아쉬운 점 또한 존재해요.
MSA가 아니지만, 분산 서버로 인한 트랜잭션 처리 문제
분산 트랜잭션
처리를 위해 Message Queue
를 도입하려고 하였으나, 시간 부족의 문제로 진행하지 않았던 점부하 테스트의 부재
위의 아쉬운 점들은 추후에 스터디를 통해서 함께 학습하고 싶은 주제이기도 합니다.
정말 긴 8달이었던 것 같아요.
프로그래밍 기초와 Java를 학습을 진행하면서 항상 늦게까지 강의실에 남아있으면서 가끔 찾아와 궁금한 것은 없는지, 힘내라고 말씀해주시던 학장님과 부학장님 그리고, Spring 과정을 배울 때 광주까지 내려와 학습 뿐 만 아니라 함께 일하고 싶은 사람의 모습을 가지고 계셨던 Dooray 수석님들 (부릉님, 만티님, 동묘님), 하루에 꼭 한 번씩은 질문해도 귀찮은 내색은 전혀 안하셨던 TA님들과 함께 했던 NHN 아카데미 4기 동기들 모두 좋은 사람이었어서 별 탈 없이 잘 마무리할 수 있어 운이 좋은 사람인 것 같습니다. ^___^
그동안 배웠던 기억을 되새기며 부족했던 점들 또한 보완해야 할 점이 많아 보인다. 이러한 점들을 보완하면서 취업 준비도 열심히 해야겠다. 함께 일하고 싶은 동료가 되기 위해 달려보자 😋
고생하셨어요:)