프로젝트 정리
시작하게된 계기
자바와 스프링을 혼자 공부하기 시작한 뒤에 처음으로 해본 프로젝트이다. 처음에는 학습이 아직 부족해서 “내가 할 수 있을까?”라는 걱정에 시작하기도 전에 겁을 먹고 시작을 고민했지만, 원래 맞으면서 배우는 것이라는 말에 용기를 가지고 시작하기로 했다. 사실 유튜브 영상이랑 구글링만으로는 성장에 한계를 느끼고 있던 상황이라 실제로 서비스를 만들어보는 경험이 필요한 시점인 것도 같았다.
주제 선정 배경
프로젝트 주제는 같이 프로젝트를 진행한 친구와 점심 메뉴를 고르다가 정하게 되었다. 점심메뉴를 정하다가 늘 먹던 거 말고 조금 색다르면서 맛있는 메뉴를 고르기 위해 카카오맵으로 검색을 하고 있었다. 그런데 프랜차이즈 음식점이 너무 많이 나오는 것을 보고 프랜차이즈를 제외한 로컬 찐 맛집을 검색할 수 있는 서비스를 만들어보고 싶다고 생각했다.
프로젝트 과정
서비스 동작에 필요한 전국 음식점 리스트는 카카오 API를 이용하여 가게명, 지역명을 통해 음식점을 검색할 수 있도록 구현하기로 하였다. 하지만 구현하는 과정에서 대형 프랜차이즈를 제외한 음식점 리스트가 필요했다. 조사를 해보니 공정거래위원회에서 프랜차이즈 브랜드에 대한 정보를 제공하고 있었지만 웹 페이지를 통해서만 조회할 수 있도록 되어있었다.
크롤링으로 데이터베이스 생성
사용자가 요청을 보냈을 때에 공정거래위원회의 웹 페이지에서도 검색 결과를 요청하는 방식으로 구현한다면, 사용자의 요청이 들어왔을 때 카카오 API에 먼저 음식점 리스트를 요청하고, 응답으로 반환된 리스트의 음식점들 마다 다시 공정거래위원회에 검색 요청을 해야 했다. 이렇게 구현하면 성능도 떨어지고 기껏 공부한 MySQL도 써볼 수 없기 때문에 크롤링으로 프랜차이즈 음식점에 대한 데이터베이스를 만들기로 했다. 다행히도 공정거래위원회 웹사이트는 모든 하위 경로에 대해 봇을 통한 접근을 허용하고 있었다. 크롤링을 해본 적은 없지만 관련 자료가 많아서 어렵지 않게 구현할 수 있었다.
크롤링으로 데이터베이스를 생성하는 부분은 음식점 리스트를, 조회 반환하는 부분과 분리하여 구현하기로 하였다. 구현하고자 하는 서비스에 필요한 기능이긴 하지만 서로 독립적으로 작동하기 때문에 서비스의 부담을 분산하고자 하였다. 또한 크롤링 동작을 실행하는 부분은 자료가 많은 파이썬의 beautifulSoup를 사용하였다. selenium이라는 선택지도 있었지만 크롤링을 진행하는 웹페이지가 모두 정적리소스로 구성되어 있었고 beautifulSoup의 성능이 selenium보다 뛰어나다는 자료가 많아서 beautifulSoup를 선택하게 되었다.
AWS
또한 실제 서비스처럼 다른 사람들도 사용할 수 있도록 배포를 해보고 싶어서 AWS를 이용하여 배포하기로 하였다. AWS를 이용하여 배포하는 방법은 프로젝트 시작 전에 공부한 내용이 아니지만 인터넷에 자료가 많아서 어렵지 않게 할 수 있었다. 물론 모든 과정들을 이해하고 AWS를 사용했다고는 할 수 없지만, 한 번 해본 경험이 있으니 다음번엔 더 수월하게 할 수 있을 것이라는 기대와 따로 공부를 할 때에 더 쉽게 이해할 수 있을 것이라는 생각이 들었다.
Github Actions
AWS를 사용하는 김에 배포 자동화도 구현해보고 싶어서 깃허브액션도 사용해 보았다. 이것도 역시 프로젝트 시작 전에 공부한 내용이 아니긴 하지만, 역시 자료가 많아서 어렵지 않게 구현할 수 있었다. 물론 AWS와 마찬가지로 완벽히 이해하고 사용한 것은 아니기 때문에 따로 학습을 해야겠다는 생각이 들었다.
프로젝트 결과
지역명, 음식 카테고리, 상호명 등을 입력받아서 프랜차이즈 음식점을 제외한 검색 결과를 보여주는 서비스를 구현하는 데에는 성공을 했지만 많은 아쉬움이 남는 결과물이었다.
일단 검색기능을 몇 번 실행하면 EC2의 CPU사용률이 99%를 찍으면서 멈춰버리는 일이 발생했다. 문제 요인이 여러 가지 있었는데 먼저 AWS의 사양이 가장 큰 요인이었던 것 같다. 메모리 용량이 너무 적어서 CPU에 부담이 커진 것이 서비스가 원활하게 동작하지 않는 원인이었던 것 같다. 사실 이 부분은 사양을 높이면 해결되는 문제여서 서비스에겐 큰 문제지만 나에겐 엄청난 문제는 아니라고 생각했다.
문제가 되는 부분은 프론트에서 받은 요청으로 원하는 결과를 만들어내는 과정이 비교적 오래 걸린다는 것이다. 현재 구현한 대로 동작을 한다면 프론트에서 받은 요청을 통해 카카오 API를 호출해서 응답을 받으면, 그 응답 내용을 하나씩 순회하며 데이터베이스에 해당 음식점이 있는지 판별하여 필터링하게 된다. 이 과정에서 카카오 API가 응답으로 반환한 리스트의 길이만큼 데이터베이스에 조회 쿼리를 실행하도록 한 것 때문에 성능저하가 발생했던 것 같다. 동작 시간으로 따지면 1~2초 내외로 별로 큰 숫자가 아닌것 처럼 느껴지지만 이런 요청이 몰리게 되면 서비스에 부담이 되기에 해결해보고 싶었다.
이 문제를 해결하고자 조사해 본 결과 IN
을 이용하여 여러 개의 검색어로 한 번에 조회하는 방법이 있다는 것을 알게 되었다. 하지만 LIKE
와 같이 사용될 수 없기 때문에 데이터베이스의 내용과 검색어가 정확히 일치하지 않으면 조회가 불가능하다는 문제가 있었다. 핑계라면 핑계겠지만 개강을 해서 지금 당장은 개선이 힘들 것 같다. 추후에 스프링에서 쿼리를 커스터마이징 하는 법에 대해 공부해서 언젠간 성능을 개선할 것이다.
느낀점
좋았던 점
처음 프로젝트를 진행하면서 역시 직접 해봐야 한다는 것을 느꼈다. 실제로 내가 원하는 서비스의 기능을 하나씩 만들어 나가면서 더 흥미를 느끼게 되었고 배운 내용을 어떻게 써야 할지 알게 되는 것 같았다. 정말 말 그대로 경험치가 쌓이는 기분이었다. 뿐만 아니라 다음에 어떤 걸 공부해야 할 지에 대해서도 자연스레 알게 되었고, 프로젝트를 진행하는 도중에도 공부했지만 잊은 내용과 부족한 내용들을 채울 수 있었다.
이번 프로젝트에서는 처음으로 학습한 내용들을 써볼 수 있는 기회였다. 기본적으로 기능 구현을 위한 스프링 프레임워크를 이용하여 API를 구현하는 것부터 MySQL을 이용한 관계형 데이터베이스의 사용, 외부 API의 사용까지 사용해 볼 수 있었고, 마지막에 AWS를 이용한 배포까지, 앞으로도 기능 구현부터 최종 완성까지 필요한 과정들을 처음으로 직접 겪어보고 방법을 익힐 수 있었다.
아쉬웠던 점
이번 프로젝트를 진행하면서 배운 것도 알게 된 것도 많지만, 처음이라 미숙해서 그런지 아쉬운 점도 많이 남았다. 일단 크롤링으로 데이터베이스를 생성하는 과정을 자동화하지 못했다는 것이 조금 아쉬웠다. 자바로 구현했다면 할 수 있었겠지만 그래도 기능적인 부담을 덜기 위해 메인 기능과 크롤링을 나누어 구현한 것은 괜찮은 방법인 것 같았다. 다음에 기회가 되면 파이썬 프레임워크를 배우거나 다른 방법을 통해 데이터베이스를 자동으로 갱신하는 방법에 대해 공부해야겠다고 생각했다.
그리고 배포과정에서도 AWS와 Github Actions에 대해서도 이해를 잘 하지 못한채로 사용했다는 게 아쉬웠다. 실제 웹 서비스처럼 만들어보고 싶어서 AWS와 Github Actions를 사용해보기로 했지만 대략적인 구성 요소와 구조 정도만 알고 제대로 이해한 상태에서 사용하지는 못 했던 것 같다. 앞으로 많이 사용하게 될 것 같아서 나중에 제대로 공부해서 이해 해봐야겠다.
무엇보다 아쉬움이 남았던 점은 성능에 대한 문제였다. 이번 프로젝트에서 메인 기능을 구현하면서 외부 API로 불러온 결과물을 데이터베이스를 조회하여 필터링을 했어야 하는데 그 과정에서 약간의 성능 저하가 발생했었다. 쿼리문을 너무 많이 실행하는 것이 문제인 것 같은데 JPQL로 적절하게 쿼리문을 커스터마이징하면 쿼리문의 실행을 줄일 수 있다는 것을 알게 되었다. 이 부분도 나중에 쿼리문 성능을 측정하고 적절한 방법을 사용하는 법에 대해 공부해야겠다.