✅ 프로젝트 소개
프로젝트명 : 모각코 ON:
- 내 위치를 중심으로 12km 이내에 있는 근처 이웃 개발자들과 함께 '모여서 각자 코딩'을 할 수 있는 온라인 서비스 플랫폼
- 목표 : 함께 하는 개발 문화가 중요한 개발자들을 위해 보다 쉽게 커뮤니티를 형성하고 유지할 수 있도록 개발 문화에 기여하기 위함
✅ 주요 기능
- 12km 이내에 위치한 이웃 개발자들과 모각코 세션을 생성하여 함께 코딩할 수 있음
- 화상 + 음성 + 일반채팅 + 화면공유가 가능하며 채팅방 내에 개인적으로 사용할 수 있는 코드에디터 기능도 제공
- 일반 채팅 시, 부적절한 언어를 사용했을 경우 쾌적한 사용 환경을 위해 필터링 적용
- 친구 기능 : 사용자의 닉네임 혹은 고유의 친구 코드를 사용하여 친구 추가를 보낼 수 있음
- 쪽지 기능 : 친구 기능과 마찬가지로 닉네임, 친구 코드를 사용하여 쪽지를 주고 받을 수 있음
- 신고 기능 : 부적절한 언행으로 불쾌감을 주었을 경우 신고 가능 ( 관리자 페이지에서 처리)
- 실시간 알림 기능 : 친구 추가가 되었거나 쪽지를 주고 받을 때 실시간으로 알림이 전송되어 확인할 수 있음
- 마이페이지 통계 데이터 : 요일별로 내가 공부한 시간과 주로 선택한 언어의 비율을 확인할 수 있음 (매주 일요일 reset)
- '코딩온도(ON°)'라는 자체적인 지표를 제공하여 오늘의 유저를 확인할 수 있음
✅ 기술 스택
- Java 17
- 자바 11 이후 가장 최신 LTS 버전임
- 새로운 기능과 최신 라이브러리를 활용할 수 있으므로 학습과정 중에 시너지 효과를 얻을 수 있다고 생각
- Spring Boot 2.7.12
- 지난 번 프로젝트에서 자바 17 + 3+ 버전을 사용해보았음 (swagger 적용 시 오류가 발생하는 등의 문제가 있었음)
그래서 이번 프로젝트에서 2.7 버전을 사용하기로 함
- OpenVidu 2.25.0
- 프로젝트의 메인 기능은 화상 채팅을 위해 사용
- WebRTC를 사용할 수도 있었으나 STUN/TURN 서버를 별도로 구현해야하기 때문에 짧은 기간에 구현할 수 있을지 의문 사항이 많았음
- 또한 우리는 화상채팅이 N:M 구조로 가능해야하고 미디어 서버의 안정성도 보장해야하기 때문에 SFU 방식의 서버가 필요했으며 추가적으로 화면공유 기능도 구현해야하는 상황
- 이러한 상황을 토대로 자료 수집 과정에 OpenVidu 라이브러리를 알게됨, 참조 자료가 많고 화상+음성채팅에 화면공유까지 제공하고 있으며 SFU 방식으로 되어있어서 적합하다고 판단
- Redis
- Access Token과 Refresh Token을 저장하기 위한 캐시 메모리로 사용 (보안 강화, 높은 성능)
- Redis Pub / Sub
- 프로젝트 기획 상 채팅 메세지를 저장할 필요가 없고 짧고 간단한 메세지를 주고 받기 때문에 사용하기로 결정함
- 비교적 단순한 구조로 되어있고 구현이 쉬운 편이기 때문에 빠른 개발을 할 수 있을 것 같아서 결정
- SSE (Server-Sent-Event)
- 실시간 알림을 사용자에게 전송하기만 하면 되기 때문에 양방향 통신이 필요없다고 생각하여 웹소켓 대신 SSE를 채택하여 적용
- Github Actions
- 이전 프로젝트에서 적용하지 못했던 CI/CD를 위해 보다 쉽게 접근 가능한 tool이 필요했음
- Jenkins도 고려해보았으나 현업에서 Jenkins가 특별한 장점이 있어서 사용하는 것이 아니라는 피드백을 근거로 비교적 시도하기 쉬운 Github Actions를 선택하게 됨
✅ 나의 경험
- 화상 채팅을 위한 룸 세션 CRUD 구현
- OpenVidu 라이브러리를 활용하여 룸 세션을 생성하고 관리하는 API 구현
- 12km 이내 룸만 조회 가능하도록 쿼리 작성하여 전체 조회 방지
- 채팅 서버 구축
- 이메일 인증 기능 구현
- CI/CD 구축
- AWS 인프라 활용
- RDS, S3 : 기본 데이터와 이미지 파일을 저장하기 위한 DB로 사용
- EC2, ACM, Route 53, ELB : https 서버 배포를 위해 사용
- CodeDeploy, S3 : Github Acitons와 함께 CI/CD를 구축하여 배포 자동화를 위해 사용
- 테스트코드 작성
- jacoco를 사용하여 코드커버리지 확인, 최종 82% 커버리지 달성
✅ Trouble Shooting
1. SSE - HikariCP DeadLock
- SSE를 구독하는 과정에서 지속적인 요청을 보낼 때, pool를 하나씩 잡고 구독이 끊어지지 않았음
- 계속된 요청에 DB에 Lock이 걸려 어떠한 요청에도 무응답인 문제가 발생함
- Nginx의 설정을 변경해주고 DB를 이관하는 등의 다양한 시도를 해보았으나 문제 해결 방법이 잘못되었다고 판단
- 구독을 끊어주는 로직이 제대로 작동하지 않고 있는 것을 발견
- 영속성 컨텍스트가 닫히도록 OSIV 설정을 변경함
- 이로 인해 데이터의 변경사항이 생길때마다 DB에 commit을 해주어야하는 상황이 발생했으나 DB에 Lock이 걸리는 문제는 해결됨
2. API 서버와 미디어 서버를 하나의 인스턴스에 배포 시도 - port 중복 문제
- 하나의 인스턴스에 두가지 서버를 띄우려는데 OpenVidu에서 기본 포트인 80와 443 포트를 사용하고 있음을 발견
- 두 가지의 포트가 겹쳐서 정상 작동하지 않는 문제가 발생함
- proxy server에 대한 공부를 좀 더 하고 포트 설정을 변경해주려고 했으나 문제가 해결되지 않았고 상당히 많은 시간을 투자함
- 결국 시간상의 문제로 인스턴스를 하나 더 생성하여 API 서버와 OpenVidu 미디어 서버를 분리하기로 함
3. 랜덤으로 발생하는 CORS 문제
- 위의 문제로 인해 서버를 분리하였더니 CORS 문제가 발생함
- 알고보니 https 로 배포하기 위해 건들였던 nginx의 cors 설정과 application 내의 cors 설정이 중첩되어 랜덤으로 요청이 되고 안되고를 반복했던 것
- nginx에서 cors 설정을 제거하여 해결함
✅ 회고
이번 프로젝트를 통해 새로운 도전에 대한 두려움이 많이 사라졌다. 화상 채팅을 어떻게 구현해야할지 막막했는데 이것저것 찾아보다 우연히 알게된 라이브러리를 새롭게 적용하는 과정 자체가 도전이었다. 새로운 것을 찾아내고 적용해서 성공해냈다는 사실이 앞으로 또 다른 도전을 해야할 상황에서 의지를 심어주는 발판이 될 것이라 생각한다.
정말 많은 기술을 만나면서 전부 다 습득한 것은 아니겠지만 프로젝트 시작 전보다 많은 성장을 해냈다는 것에 뿌듯함을 느끼고 문제 해결을 위해 어떤 것이든 일단 적용해보아야겠다는 생각을 가지게 되었다.
특히 테스트코드를 작성함에 있어서 의의를 알게 되었다. 처음 테스트코드가 중요하다는 것을 들었을 때, 테스트코드 작성하는 것 자체가 너무 부담스러웠고 제대로 코드가 작성되고 있는지 끊임없는 의문이 있었다. 하지만 코드 커버리지가 82%에 달성했을 때, 코드가 우리의 의도대로 정상 작동하고 있다는 fact가 주는 자신감이 어떤 것인지, 코드에 대한 믿음이 생긴다는 것이 무슨 뜻인지 알게 되었다.
개발이라는 것이 그런 것 같다. 처음 한 번 보면 아무것도 모르겠지만 계속해서 들여다보면 결국은 이해가 되고 해결법이 눈에 보인다. 꾸준함을 무기로 더 나아가야겠다는 교훈을 얻은 프로젝트였다.
'T.I.L. :: Today I Learned > 항해99 14기 본과정' 카테고리의 다른 글
항해99, 수료! (0) | 2023.07.07 |
---|---|
Day 89. Final 최종 발표회까지 마친 하루 (0) | 2023.06.30 |
Day 88. 최종 제출 완료...😭 (0) | 2023.06.29 |
Day 87. 코드 커버리지 70%가 눈 앞! (0) | 2023.06.28 |
Day 86. 테스트코드 쓰는 거 재밌당 ㅎㅋㅎㅋㅎ (0) | 2023.06.27 |