'아이북조아'는 LG 유플러스 유레카 백엔드 비대면 1기 교육과정을 수료하며 진행한 종합 프로젝트입니다.
최종 융합 프로젝트에 들어가기 전 백엔드 6명이서 진행하였습니다.
GitHub - ureca-Integrated/backend: 🏆 LG U+ 유레카 1기 백엔드 비대면 최우수상 종합 프로젝트
🏆 LG U+ 유레카 1기 백엔드 비대면 최우수상 종합 프로젝트. Contribute to ureca-Integrated/backend development by creating an account on GitHub.
github.com
프로젝트 진행
애자일 방법론
'아이북조아'는 애자일 방법론을 활용했습니다. 팀원들이 스프린트에 맞춰 개발을 착실히 해 주어 일정 관리에 거의 어려움이 없었습니다. ( 다들 너무 열심히 해서 일정보다 빠르게 끝날때도 있었습니다. ㅎ )
Jira를 통해서는 다음의 과정을 통해 일정을 관리하였습니다.
- 유저 스토리와 에픽을 구분하여 기능별 세부 작업 작성
- 플래닝 포커를 통해 스토리 포인트를 산정하여 작업의 복잡도와 우선순위를 설정
- 매일 짧은 스크럼을 통해 유연한 일정 및 우선순위 관리
- 매주 스프린트 계획을 세우고 목표를 설정하여 효율적으로 진행 상황을 관리
매일 아침에 스크럼 회의를 진행하면서 팀별 개발 상황을 공유했고 노션에 정리하였습니다.
페어 프로그래밍
'아이북조아'는 페어 프로그래밍으로 개발을 진행했습니다.
저희는 필수 기능을 2명씩 나누어 팀을 구성하고, 추가 기능은 3명씩 나누어 진행했습니다.
페어 프로그래밍은 함께 방향을 논의하고 서로의 코드를 리뷰하는 방식으로 진행했습니다. 솔직히 페어 프로그래밍을 시작하기 전에는 부담스럽기도 했고 잘 맞지 않으면 어떡하나 하는 걱정이 있었습니다. 그러나 직접 경험해 보니 생각보다 많은 장점이 있었습니다.
비대면 교육 환경이었기 때문에 제 페어였던 도림이와 개발할 때는 한 명이 화면을 공유하며 코딩을 진행하고, 다른 한 명은 실시간으로 피드백을 주는 방식으로 협업했습니다.
장점
- 저와 도림이 둘 다 제대로 된 프로젝트는 처음이어서 Git 컨벤션과 코딩 컨벤션을 지키는 것이 서툴렀지만, 페어 프로그래밍 덕분에 서로 즉각적인 피드백을 주고받을 수 있었습니다.
- 도림이의 코딩 스타일이 저와 조금 달랐는데 그 과정에서 배울 점이 많아 유익했습니다.
- 서로의 코드를 작성하고 이에 대한 질문과 답변을 주고받으며 보다 이유 있는 코드를 작성할 수 있었습니다.
- 주말까지 함께 개발하면서 자연스럽게 빠르게 친해질 수 있었습니다.
단점
- 혼자 개발할 때보다 시간이 더 오래 걸린다는 점이 있었습니다.
구현 과정
이 전에 아주 간단하게 쇼핑몰 CRUD만 해봐서 CRUD는 쉽겠지라고 생각했는데
ERD가 복잡하면 CRUD도 신경쓸 게 많고 어렵구나라는 걸 이 때 깨달았습니다.
이 부분은 페어인 도림이와 함께 천천히 구현해 성공했습니다.
성향 삭제를 할 때 처음에는 deletAll() 활용했습니다.
이 부분은 신지님이 deletAllInBatch()를 활용해 보는 것이 어떠냐는 코드 리뷰를 남겨주셔서
데이터를 한 번에 삭제할 수 있도록 해결했습니다.
또한 삭제는 연관 관계 때문에 순서가 매우 중요하구나를 깨닫게 되었습니다.
다음으로는 1분당 10만 요청을 안정적이게 처리해야하는 응모 이벤트를 구현해야했습니다.
이걸 구현하면서 Redis도 처음 써봤습니다.
처음에는 이벤트 유효성 검사를 MySQL을 조회하는 방식으로 처리했는데, 이를 한 트랜잭션 안에서 함께 수행하는, 지금 생각해보면 정말 비효율적인 코드를 작성했었습니다.
멘토링을 받으면서 멘토님께서 그렇게 하면 Redis를 사용하는 의미가 전혀 없어진다고 피드백해 주셨습니다.
그 조언을 바탕으로 코드를 수정하여, 이벤트를 등록할 때 이벤트 시간을 Redis에 저장하고, 이후 이벤트 유효성 검사 시 MySQL이 아닌 Redis를 조회하도록 개선했습니다.
SET 자료형과 Lua Script를 활용으로 중복을 원자성을 보장하여 중복을 방지했습니다.
Redis는 단일 스레드로 동작하지만 동시에 여러 클라이언트에서 요청을 보낼 경우 중복이 발생할 수 있다는 사실을 알았습니다. 단일 스레드라는 것은 한 번에 하나의 명령어만 처리한다는 의미이지만 여러 개의 요청이 동시에 Redis에 도착하면 순서를 보장할 수 없기 때문입니다.
특히 SETNX(키가 없을 때만 저장)나 SET NX EX(키가 없을 때만 저장 + TTL 설정)를 사용하더라도 분산 서버 환경에서는 거의 동시에 같은 요청이 들어올 경우 중복이 발생할 수 있습니다. 이를 방지하기 위해 SET 자료형과 Lua 스크립트를 활용하여 원자성을 보장하는 방식을 적용하였습니다.
1분당 10만 요청을 안정적으로 처리해야하는 게 요구사항이기 때문에 부하 테스트가 필요했씁니다.
JMeter 통해 시스템의 성능을 개선하고 중복 요청이 발생하지 않는지 확인했습니다.
JMeter를 처음 사용해봤는데 익숙해지는 데 꽤 시간이 걸렸습니다.
저뿐만 아니라 도림이와 시은이 모두 이 부분은 처음이었기 때문에, 함께 열심히 자료를 찾아보고 공부하면서 결국 구현에 성공했습니다.
다만 프로젝트 기간이 짧았고 이 부분이 추가 기능이다 보니 충분한 시간을 투자하기 어려워 깊이 있게 공부하지는 못했습니다.
향후에는 Redis와 Lua Script에 대해 더 자세히 학습하고, 코드를 리팩토링해보면 좋을 것 같습니다.
발표 영상
시은이가 시나리오를 작성한 뒤 TTS를 활용해 발표 영상을 만들면 재미있을 것 같다고 제안해서 실제로 TTS를 활용하여 영상을 제작했습니다.
개발을 하면서 영상 편집까지 하게 될 줄 몰랐는데 막상 해보니 생각보다 재미있게 만들 수 있었습니다.
제출 마감 시간이 거의 다 됐을 때 갑자기 프로그램이 튕기면서 파일이 날아가는 바람에 정말 깜짝 놀랐지만, 다행히 이전에 한 번 내보낸 파일이 있어서 시간 내에 제출할 수 있었습니다. (그때는 정말 식겁했습니다..)
후기
강사님께서 이번 프로젝트에서 팀장에게 가장 중요한 것은 소통이라고 하셨고 저도 한 번 도전해보고 싶어서 팀장을 맡게 되었습니다. 하지만 본격적으로 진행하는 Spring 프로젝트는 처음이라 부담이 되기도 했습니다.
그럼에도 불구하고 모든 팀원들이 정말 잘해주었고 열정적으로 임해 준 덕분에 좋은 성과를 얻을 수 있었습니다.
특히 항상 코드 리뷰에 적극적으로 참여하고 성능 개선과 다양한 상황을 고민하며 코드를 발전시켜 나가는 신지님을 보면서 정말 많은 것을 배웠습니다.
이번 프로젝트를 통해 API 명세서 작성, Git 컨벤션 등 거의 모든 것이 처음이었지만 운이 좋게 팀장도 하고
팀원들 모두가 적극적으로 참여하고 협력해 주어 큰 도움이 되었습니다.
3주 동안 거의 매일 새벽까지 쉬지 않고 개발하고 마지막 날에 영상 편집할 때는 지쳤는데 결과물이 좋은 걸 보니
기분이 좋아지고 이래서 개발자하는 건가 생각하게 되는 프로젝트였습니다.
팀원들과 가끔씩 연락하고 오래 보는 사이가 되었으면...