이번 포스팅에서는 헤이동동 서비스 소개와 기획에 대해 설명하고, 이를 바탕으로 설계한 시스템 구조와 프로세스에 대해 설명한다.
우리 학교 공대 생협은 공대 규모와 이용자 수에 비해 턱 없이 좁고 작은 공간을 갖고 있다. 매장을 직원 두 분이서 운영하는데, 카운터, 상품 정리 및 진열, 음료 제조 모두 두 분이서 다 하시기 때문에 적은 인력으로 아주 바쁘게 돌아간다. 쉬는 시간에는 컨베이어 벨트라는 말이 있을 정도로 학생들이 매장 밖까지 줄을 길게 서 있으며, 음료를 주문하고 수령하는 데에는 그만큼 시간이 오래 걸린다.
헤이동동은 이렇게 짧은 쉬는 시간 안에 생협에서 음료를 사 마시기 힘들다는 현실적이고 직관적인 문제를 IT 기술을 활용해 해결해보고자 시작된 프로젝트다.
우리가 아주 편리하게 사용하고 있는 스타벅스의 사이렌 오더처럼, 미리 음료를 주문하고 간편하게 주문할 수 있는 서비스가 있다면 생협 이용자와 매장 관리자 모두에게 좋을 것이라 생각했다. 따라서 이러한 음료 원격 주문 서비스를 목표로 잡고, 세부 기획과 설계를 진행하게 되었다.
서비스 구현을 위한 전체적인 시스템의 구조는 다음과 같다.
서버는 Spring Boot
를 사용하여 구현했다. 하나의 서버가 모든 클라이언트의 HTTP 요청을 처리하도록 했으며, DB와의 통신은 서버가 담당하도록 했다. 또한, 클라이언트인 Customer와 Administrator은 Vue.js
를 통해 별도의 프로젝트로 구현했다.
원래는 각 클라이언트마다 별개의 서버를 두고 각각 운용하면서 두 서버 간 Socket
통신을 구현하여 실시간 주문 처리를 하려고 했다. 하지만, 서버 간 소켓 통신이 아니라 클라이언트 간 통신이나 클라이언트-서버 간 실시간 통신을 구현할 수 있는 방법이 존재하고, 서버 2개를 운용하는 비용에 비해 메리트가 없기 때문에 다른 방안을 모색했다.
산학멘토링을 진행할 때 멘토님께서 제안하신 방안은 클라이언트 사이에 MQTT
서버를 두고 실시간 통신을 구현하라는 것이었다. 두 클라이언트 사이에 Socket 통신을 구현할 수도 있지만, MQTT Pub-Sub은 배달의 민족 등의 주문 어플에서 자주 쓰이는 구조이고, 도전해볼만한 흥미로운 기술이기 때문에 추천을 해주셨다. 하지만 현실적인 한계로 인해 MQTT보다 간단하고 효율적인 통신 구조를 도입하기로 결정했다.
최종적으로 클라이언트 간 통신은 HTTP Pooling
방식으로 구현하게 되었다. HTTP Pooling 짧은 주기를 설정하여 그 주기마다 request를 보내 변동사항에 대해 통신을 주고 받는 것이다. 정말 끊임없이 request와 response가 오고 가기 때문에 약간의 오버헤드는 있을 것 같다. 하지만 클라이언트 간 Socket 통신은 담당 팀원이 해결할 수 없는 에러가 발생하여 Pooling 방식을 택하여 구현하게 되었다.
위 의 3가지 로직 중, 주문 로직을 구현하기 위한 시퀀스 다이어그램은 다음과 같다.
주문 프로세스에서 매장 선택과 고객의 메뉴 선택 화면은 생략되었다. 또한 고객과 관리자, 그리고 서버 사이의 통신에 집중하여 시퀀스 다이어그램을 작성하였다.
실제 코드로 구현하기 전 기획과 설계에 대해 기록을 남기고 문서화하는 것이 아주 중요하다는 것을 느낄 수 있었다. 아무리 회의하는 중에 대화를 많이 하고 기억을 하려고 노력한다고 하더라도, 기억은 왜곡될 뿐 아니라, 각자 이해하고 있는 부분에 차이가 있을 수 있기 때문이다. 이 때 글과 문서로 정리하면 정리하는 과정에서 더 명확하게 논의를 할 수 있고 잊어버려도 기록을 확인하면 된다.
또한 설계, 기획의 변동사항을 꾸준히 팔로업하여 설계도를 작성하고, 관련 내용을 문서화하는 것이 아주 중요하다는 것을 프로젝트 경험을 통해 몸소 느낄 수 있었다. 기록을 남겨야 실제로 코드로 구현할 때 정확히 어느 시점에 어떤 기능을 추가해야 하는 지, 어떤 값을 input과 output으로 설정해야 하는 지 정확하게 알 수 있다. 소통을 아무리 잘 해도 변동사항은 구현 전이든 하는 중이든 끊임없이 발생하기 마련이다.