나는 IT 동아리를 한번쯤은 해보고 싶은 마음이 있었다. 한창 진로 고민을 많이 하던 중에 내가 부러워하는 것들을 나열해보고 하나씩 도전해보기 시작했고 그 중 하나가 cmc 활동이었다.
운이 좋게 서류 합격을 거쳐 최종합격까지 하게 되었고 😆
OT 날에는 정말 최선을 다해 서비스를 개발해보기로 다짐했다.
직무 고민도 하던 때라 QA 업무를 제대로 진행해보고 싶었고, 취업을 위해 프로젝트를 하는 것이 아닌 좋은 서비스를 개발 자체를 목표로 삼기로 결정했다.
cmc 활동을 본격적으로 시작하기 전에 명확한 니즈에 의해 필요한 기술만을 도입한 프로젝트를 봤다. 남들이 해서 이것저것 하는 게 아니라 서비스 기획에 맞게 구조를 고민하고 모놀리식의 한계를 직접 느껴 멀티 모듈을 전환한 프로젝트의 과정을 보면서 나도 저런 니즈와 개선의 과정을 느껴보고 싶었다.
cmc 17기 활동은 다음과 같이 진행되었다.
서버 파트 챌린저들은 최종 팀빌딩 전에는 팀빌딩 세션이 없어서 스터디를 진행했다.
서비스 기획부터 출시까지 약 두달이 주어지며 개발 기간은 약 6주이다.
cmc는 다른 동아리들과 다르게 각 파트 당 1명이고 ios, 안드로이드를 모든 팀이 출시해야 한다. 개발 기간도 짧아서 정말 만만치 않았다..
umc + cmc 의 합동 해커톤이 cmc의 첫 활동이다. 주제는 환경, 23시간 동안 진행되었고 우리팀은 냉장고 재고 관리 서비스 냉집사
를 개발했다.
처음 참여하는 해커톤이라 부족한 부분도 많았지만 다음에 참여한다면 아이디에이션에 초점을 맞출 것 같다. 해커톤의 묘미는 재미
니까 수익화에 초점을 맞춘다기보다 독창적인 아이디어를 생각해보는 게 좋을 것 같다. 자세한 후기는 여기서 볼 수 있다.
1차 스터디는 Data Dog에 재직 중인 cmc OB 분을 모셔 발표를 듣고 실습을 진행했다.
다음과 같은 요구사항을 aws에 직접 구축해보았다.
외부로부터 application server에 연결할 수 없도록 application server를 private subnet에 배치해주세요. 다만, 이 application server는 외부 API로부터 교통 정보를 받아와 연산을 처리합니다. 따라서, application server는 Internet으로부터 정보를 가져올 수 있어야 합니다.
내가 만드는 것들이 private subnet에 위치하는지 public subnet에 위치하는지 생각 없이 만들었었는데 private subnet과 public subnet의 차이는 무엇인지 확실히 이해할 수 있는 시간이라 유익했다.
vpc끼리 통신하려면 인터넷 게이트웨이가 필요하지만, vpc peering를 이용하면 더 효율적으로 사용할 수 있다는 것도 알게 되었다.
2차 스터디는 cmc adviser였던 똘이님의 짧은 발표로 진행되었다.
주제는 서버란 무엇인가?
였는데 아래 질문에 대한 답이 가능하냐고 일침을 날리셨다..😬
- Spring과 Spring Boot는 어떤 차이가 있나요? 답변 보기
- 서버는 무엇인가요?
- Rest 통신이 발전하게 된 이유는 무엇인가요?
- 서버리스 아키텍처에서 aws lamda는 어떻게 rds와 커넥션을 맺나요?
- 스프링 시큐리티에서 있는 필터는 어떻게 IoC 컨테이너를 사용하나요?
- MSA 아키텍처에서 DB 조인 연산이 필요한 경우 어떻게 해결할 것인가요?
우리 팀(약쟁이들)이 만든 서비스는 서로 약 먹었는지 잔소리 해줄 수 있는 앱 약쏙이다.
기존 시장에는 개인이 복약을 관리하는 형식이 많은데, 누군가 챙겨줘서 그래서 섭취가 편한 서비스를 만들어보자는 멋진 기획자님의 아이디어✨였다.
서로 메이트 팔로우가 가능하고, 미복용 상태면 잔소리를 보낼 수 있다. 쉽게 오늘 복용 정보를 확인할 수 있게 위젯도 개발했다!
스케줄을 관리하는 서비스에서는 스케줄링이 필수적이다.
만약 버그가 발생한다면 DB 데이터가 쉽게 오염될 수 있고, 최악의 경우 서비스 중단과 롤백 작업까지 이어질 수 있다. 특히 스케줄 종료나 수정 기능은 고려해야 할 변수가 많아 그만큼 복잡하면서도 중요한 영역이다.
그중 고민을 많이 했던 요구사항은 종료일 없음
옵션이었다.
유저의 입장에서 복약 종료일 없음을 선택할 수 있다면 훨씬 편해질거라 예상했고 이 기능을 도입하기 위해 미래의 스케줄은 DB에 insert하지 않고 dto로 보여주는 on the fly 방식을 채택했다.
자세한 내용은 여기서 볼 수 있다.
약쏙의 메인 기능인 알림 기능의 응답 속도를 높이기 위해서 비동기 처리를 위해 메시지 브로커를 도입하기로 결정했다. SQS, RabbitMQ, Kafka중에 무엇을 쓸지 고민했고, 당시 복용 시간이 "30분" 지났는데도 안먹었으면 보내주는 리마인드 알림
을 구현하기 위해 SQS는 탈락. 이벤트 아키텍처를 도입하는게 아니라 단지 알림 비동기 처리를 원했고 개발 기간 내에 트레이드 오프가 커질 것으로 예상했기에 Kafka가 아닌 RabbitMQ를 선택하게 되었다.
실제 FCM 전송 지연을 모사하기 위해, 알림 로직에 sleep(1) 처리를 추가한 후 부하 테스트를 수행했고 속도 개선을 확인할 수 있었다. (동시 사용자 수 30명, 1분 동안 수행함)
구분 | 큐 도입 전 | 큐 도입 후 |
---|---|---|
평균 응답 시간 | 1.1초 | 36ms |
최대 응답 시간 | 3.28초 | 274ms |
요청 수 | 435회 | 870회 |
초당 처리량 | 7 req/s | 14 req/s |
사용자 경험을 개선하기 위해 다중 알림을 구현했다. 여러 기기에 로그인 한 유저라면 해당 기기들에 알림들을 보내준다. 이를 위해 유저와 유저 기기는 일대다 관계(유저1 - 유저기기n)로 설정했다.
다중 기기를 고려하면서는 생각해야 할 것들이 많았는데, 기기의 fcm token이 바뀐건지 기기가 바뀐건지 서버에서는 알 수 없기 때문에 프론트에게 device id를 받았다.
그리고 로그아웃의 경우 해당 기기만 로그아웃 해야 하기 때문에 device id를 요청값으로 받아야 했다.
하나의 기기를 여러 유저가 사용하는 경우 마지막으로 로그인 한 유저의 알림만 발송해야 했기에 이미 등록된 기기라면 소유권을 이전하는 로직을 추가했다.
데모데이에서 알림이 내 아이패드와 아이폰에 동시에 오는 것을 볼 때 마다 구현하길 잘했다고 생각했다. 이런 디테일을 고려한 개발을 하고 싶었다구
cpu 상태 모니터링
프로메테우스랑 그라파나로 cpu 상태를 모니터링했다.
지금은 서버 비용 문제로 모니터링 서버는 중지했지만 만약 api 서버에 장애가 생겨 다운 되면 모니터링 서버가 이를 알려줘야 했기에 서버 스케일업이 아닌 스케일아웃을 진행했다.
500 에러 모니터링
로그백으로 예상하지 못한 500에러가 발생할 때 마다 슬랙으로 알림을 보내게 만들었다.
rabbit mq 컨테이너를 찾지 못할 때, 클라이언트에서 내가 예상하지 못한 잘못된 요청을 보내고 있을 때, 동시성 이슈로 db에 락이 걸려 데이터 수정을 할 수 없을 때 등 다양한 상황에 알림을 받아 버그를 잡을 수 있었다.
슬로우 쿼리 모니터링
mysql 슬로우 쿼리를 로그를 cloud watch에 집계해 aws lamda를 이용해 이벤트 발생 시 슬랙으로 알림이 전송되게 했다.
1초 이상의 쿼리를 보내게 설정했고, 대부분은 데몬에서 히스토리를 조회하는 sql이었지만 간혹 복약 정보를 조회해 알림을 보내주는 api에서 1초 이상의 슬로우 쿼리가 발생했다.
이번 프로젝트에서는 nginx가 아닌 nginx proxy manager로 https 설정을 했다.
8080 포트로 리다이렉트 하는 설정, http -> https로 리다이렉트 하는 설정과 SSL 인증서 발급을 UI 툴로 쉽게 진행할 수 있었다.
서비스 기획을 처음 접한 순간부터 역할이 많이 다르다고 생각해서 알림 서버, 배치 서버, api 서버로 분리할 생각이었다. 하지만 나의 예상만으로 멀티모듈을 도입하고 싶지 않았고 데이터를 기반한 문제 인식과 개선을 하고 싶었기에 모놀리식으로 진행했었다.
api를 한달만에 완성하고 남은 시간은 구조 개선을 하고 싶었지만 버그 잡고 테스트 코드 작성하느라 시간을 다 써버려서 멀티 모듈을 적용하지는 못했는데 데모데이 이후 차차 적용해나갈 생각이다.
서버 리드 분이랑 얘기를 나눴을 때도 스케줄링이 있는 서비스는 만약 서버가 다운되면 데이터가 꼬여 대장애(!)를 겪을 수 있기 때문에 하나의 서버를 쓰더라도 모듈 분리를 해보라고 권유하셨다.
런칭 후 다른 팀들의 앱들을 다 설치하고 혼자서 QA를 해봤다.
로그인 할 때 닉네임에 초성이 들어갔을 때 어떤 응답을 보여주는지, 버튼을 여러번 클릭하면 어떻게 되는지, 알림/사진 권한을 거부하면 어떻게 동작하는지, 탈퇴 하면 OAuth 연동은 끊어주고 있는지 등 여러 케이스를 생각하면서 버그와 UX에 맞지 않는 UI를 메모장에 적었다.
프로젝트를 진행하면서도 발생할 수 있는 엣지 케이스를 생각해 개발 단계에서 문제를 방지하는 과정이 재밌었다.
이 과정이 참 재밌었고 집요하게 다른 팀에 찾아가서 이거 안되는데요?
를 시전했다. 아무래도 비평이 적성인 듯.. 다른 팀들이 QA로 고용하겠다고 해주었다 ㅎㅎ
cmc에서 QA를 제대로 해보고 싶은 마음이 있었지만 백엔드 개발만으로 벅차서 하지 못했는데 앞으로 스크립트를 꼼꼼히 작성하면서 도전해보고 싶다.
이틀 간 데모데이에서 부스를 운영하며 유저를 모았다. 팀원들 모두 약사 가운을 입고 앱 설치를 해주는 사람들에게 약 봉투 간식을 증정했다 💊
umc 분들이 많이 방문해주셨고 백엔드 분이 오시면 서버 아키텍처 사진과 함께 왜 이렇게 개발하게 되었는지 백엔드에 초점을 맞춰 설명을 했다.
나도 아직 많이 부족한데 대단하다고 배우고 싶다며 서버 아키텍처 사진을 찍어가는 사람들이 있어 뿌듯했다.
데모데이 후 유저 수는 총 108명이었고 앱 스토어 36위에 오르는 경험도 할 수 있었다.
책임감 있는 팀원들과 함께 해서 출시까지 할 수 있었던 것 같다.
원활하게 개발이 진행 될 수 있도록 데일리 스크럼을 요구하고 게더에 모여 합동 개발을 하자고 했던 PM분과 완성도 있는 디자인을 보여주신 디자이너분, 데모데이 전날 위젯까지 목표로 했던 기능을 모두 완료해준 ios/안드로이드 개발자분 다들 너무 감사합니다 !!
파트 별 한명이라 걱정을 많이 했는데 다들 시간 내서 작업해주고 안되는 날에는 작업이 어려울 것 같다고 말해주어 좋았다. 지라와 깃헙을 연동해서 진행 상태도 실시간으로 확인할 수 있었다.
원하는 팀에 들어와 몰입했던 시간들이 정말 행복했다.
파트 별 한명이라는 특징이 누군가에게는 단점일 수 있지만 빠르게 개발 할 수 있다는 점과 내가 적용하고 싶은 기술을 사용할 수 있다는 점이 장점으로 작용하기도 한다. cmc가 데모데이 규모도 크고 기업 연계도 되어있어 한번쯤 도전하길 추천한다.
👜 Yakssok Repository
📲 App Download Link
ㅎㅎ 노을님 글 너무 잘 읽었고 덕분에 많이 배웠습니다 ~ 다음에 기회 되면 또 봬요 ! 파이팅!!!