커리큘럼
home
React
home

Merge OverFlow

Specialty
Node.js
FE Github
BE GitHub
Specialty
날짜

프로젝트 소개

Logo / Mascot

서비스 기획 의도

개발자의, 개발자에 의한, 개발자를 위한 만남 서비스! 상대의 프로필을 보고 이상형을 찾을 수도 있고, 당신에게 필요한 기술을 가진 협업자를 찾을 수도 있습니다!

서비스 핵심 기능

Search

서비스 아키텍처

기술 스택 및 기술적 의사결정

BACKEND

선택한 기술 스택
선택한 이유
NestJS
효율적이고 확장 가능한 서버를 구축하기 위한 강력한 기능 세트를 제공하는 강력한 Node.js 프레임워크입니다. 모듈식 아키텍처, TypeScript 지원, 내장된 최적화 기능을 통해 복잡한 애플리케이션을 쉽게 관리하고 코드 품질을 유지할 수 있습니다.
Socket.io
Socket.IO는 WebSocket 프로토콜을 기반으로 하는 라이브러리로, 뛰어난 환경 호환성과 안정성을 제공하여 1대1 매칭 시 실시간 채팅과 즉각적인 알림을 원활하게 구현하고, 여러 채팅방을 손쉽게 관리할 수 있어 우리 서비스에 적용했습니다.
Redis Pub/Sub
로드밸런서를 통해 분산된 서버 환경에서도 소켓 연결을 일관되게 유지하기 위해, Redis 어댑터와 Pub/Sub 기능을 사용해 통합적인 연결 관리를 구현했습니다. Redis의 Pub/Sub 기능을 통해 각 서버 간의 메시지와 이벤트를 실시간으로 동기화하여, 모든 서버에서 일관된 소켓 연결 상태를 유지할 수 있도록 했습니다.
TypeORM
TypeScript 기반의 프로젝트에서 SQL 쿼리를 쉽고 직관적으로 다루기 위해서 채택했습니다. TypeORM은 기본적으로 제공되는 기능 외에도 원하는 기능을 자유롭게 추가할 수 있으며, 미래에 프로젝트가 성장할 때 확장하기도 더 쉽습니다. 또한 우리가 원하는 기능을 정확하게 구현하기 위해서나 수정 및 변경과 같은 기능은 유연성이 필요한데 그러한 면모에서 TypeORM이 적합하다고 생각하여 채택하게 되었습니다.

FRONTEND

Tech Stack
적용 이유
Bubble.io
차세대 유망 노코드 기술로서, 프론트엔드 기술 지식(React)이 없어도 Bubble.io를 활용하면 백엔드 기술과 결합하여 원하는 프론트엔드 서비스를 빠르고 가시적으로 구현할 수 있습니다. 이러한 높은 활용성 때문에 Bubble.io를 선택하게 되었습니다.

Database

Tech Stack
적용 이유
AWS S3
사용자의 프로필 이미지를 손실 없이 안전하게 저장하고, 이미지 데이터의 백업을 효과적으로 관리하기 위해 채택 및 사용하였습니다.
MySQL
채팅 서비스는 대부분 읽기 작업이 많고 실시간 데이터 처리가 중요하므로, 빠른 성능과 간단한 쿼리 처리에 강점이 있는 MySQL을 선택했습니다. MySQL은 사용이 간단하고, 트랜잭션과 ACID 규칙을 통해 데이터의 정확성과 안전성을 보장할 수 있어 적합하다고 생각하여 사용했습니다.
Redis
Redis를 사용함으로써, 휘발성이 높은 데이터를 효과적으로 관리할 수 있는 고성능 인메모리 저장소를 확보했습니다. 이를 통해 SMS 인증, 전화번호 인증, 리프레시 토큰 관리 등 다양한 인증 및 세션 관련 기능을 TTL 설정을 통해 효율적으로 처리할 수 있으며, 사용자 경험을 개선하는 동시에 시스템의 보안성과 성능을 최적화할 수 있었습니다.

DevOps / Infra

Tech Stack
적용 이유
GitHub Actions
5명의 팀원이 각자의 코드를 작성한 후 GitHub에 푸시할 때, CI/CD 파이프라인을 통해 자동으로 코드 검사, 통합, 배포를 처리해 줍니다. 이에 따라 코드 수정이 자주 필요한 우리 팀의 특성상 GitHub Actions를 채택하는 것이 필수적이라고 생각했습니다.
Elastic Load Balancing
채팅 서비스의 특성상 과부하를 예방하고, 장애가 발생하더라도 자동 복구 기능을 통해 유연하게 대처할 수 있도록 ELB를 적용했습니다. 또한, 차후 서비스의 범용성과 확장성을 고려하여 이 기술을 선택했습니다.
artillery
핵심 기술에 따른 과부하 테스트를 통해 서비스의 한계 지점을 파악하고 현재 서비스가 얼마나 많은 접속자를 수용할 수 있는지 확인 및 개선하기 위해 아틀러리를 사용했습니다. 아틀러리는 소켓 연결 테스트와 다양한 시나리오 설정을 통해 부하 테스트를 세밀하고 간편하게 수행할 수 있다는 장점을 갖고 있습니다.

 트러블 슈팅

 추후 기술적인 도전 계획

저희 팀에서는 초기 기획 단계부터 마지막까지 고려 했었던 부분이 서비스의 기능 향상”과 “범용성” 및 “확장성이였습니다. 따라서 저희가 도전해 보고 싶었던 기능을 융합하여 저희 서비스를 더욱더 개선 및 고도화 해야 한다고 생각했습니다.
Docker : 어떠한 환경에서도 구동이 되는 범용성과 차후 확장성을 생각하여 적용을 생각했습니다.
환경성 : 일관된 환경을 보장한다는 것은 개발자가 개발에 따른 버전의 차이로 인한 오류를 걱정하지 않아도 된다는 장점이 있습니다. 또한 도커의 기능을 활용하여 모든 서버에서 동일하게 동작하도록 할 수 있습니다.
효율성 : 불필요한 자원 사용이나 환경 설정 충동 등을 예방 할 수 있고 그로 인하여 안정적인 운영을 만들 수 있습니다.
안정성 : 차후 미래에 실제 런칭이 된다고 했을 때 다른 언어로 개발된 기술을 격리된 환경을 제공하여 서비스에 문제를 일으키지 않습니다.
마이크로 아키텍처 : 잦은 수정이 필요한 서비스에서 수정한 부분만 업데이트해서 적은 리소스로 배포할 수 있고 그로 인하여 불필요한 배포를 없앨 수 있습니다.
Replication DB : 서비스의 특성상 DB를 수정할 때마다 서비스가 정지가 되는데 잦은 수정에 의해 서비스가 정지가 되는 불상사를 예방하고 서비스가 지속되는 기능을 향유하기 위해 고려하고 있습니다.
Pre-Signed URL : 현재는 S3에 업로드하는 이미지 URL이 그대로 DB에 같이 반영되어 기능적으로는 문제가 없지만 서비스를 사용하는 인원이 증대함에 따라 DB에 부하되는 가중치가 기하급수적으로 증가 되기 때문에 이러한 문제를 해결하기 위해서 영구적 이미지 URL이 아닌 일시적 이미지 URL을 생성하고 또한 이미지에 대한 보안성을 증가 시키기 위하여 적용할 계획입니다.

유저 테스트 결과 분석

유저 피드백 참여 인원 (총 19명)
유저 테스트 결과 분석 및 피드백 자체 평가
긍정 평가
총인원 19명16명 대다수 “만족” 이상의 만족도를 투표한 것을 확인하였습니다.
전반적인 평가로 서비스흥미많이 느끼며 개발 의도에 맞게 사용해 주셨습니다. 이는 만족도 평가와 같이 연계되어 나온 결과라고 생각됩니다.
유저들은 주로 현재의 서비스가 더 개발되기를 희망하며 서비스 기획 의도에 맞게 실제 평가로 [“재미있다.”, “하트를 쓰는 재미가 있다.”, “회원 가입에 신경 많이 쓴 것이 느낀다. 높은 완성도의 서비스를 만드느라 고생했다.”, “기획 의도가 참신했다” ]등의 의견을 주었습니다.
부정 평가
“로그인이 되지 않음, 입력값의 저장 및 반환이 제대로 안 됨, 채팅 내역이 보이지 않음, 선호도 선택 입력 미적용” 등의 기술적인 오류 피드백을 많이 받았고 받는 즉시 실시간으로 원인을 파악하여 보완하여 오류를 수정하였습니다.
아이콘의 설명이 없어서 직관적인 이해가 어렵다는 피드백을 받아 마우스를 가져다 대면 해당 아이콘의 설명이 나오도록 보완하였습니다.
유저 중 위치 파악을 선택하지 않아 거리가 0 km로 나오는 유저가 많았습니다. 따라서 위치 설정을 하지 않은 사람은 “알 수 없음”으로 표기하여 수정했고, 추가적으로 사용자가 서비스 사용법을 알기 쉽게 가이드라인을 만들 예정입니다.
새로운 의견
하트 결제 기능, 원하는 조건의 사람에게만 프로필을 공개하는 필터 기능, 채팅 시 사진도 전송 할 수 있는 기능, 나를 좋아요 한 사람의 프로필을 볼 수 있는 기능, 회원 가입 시 애인 유무 표시 등을 기타 여러 가지 기능들이 추가되었으면 좋을 것 같다는 의견을 주셨습니다.

유저 피드백 개선 방향 및 계획

앱 서비스 구현 과제
초기 기획 단계에서 설계했던 기능들이기에 피드백 받은 의견을 수용하여 서비스를 개선하고 고도화할 예정입니다.
예정 구현 과제
결제: 토스페이먼츠를 사용한 결제 시스템을 구현할 계획입니다. 유저는 결제를 통해 멤버십을 구매할 수 있으며, 멤버십 등급에 따라 하트 개수 증가, 나에게 '좋아요'를 한 유저의 프로필 보기, '좋아요' 한 유저에게 다시 '좋아요' 하기 등 다양한 기능을 사용할 수 있게 됩니다.
사진 전송: S3를 통한 사진 업로드 API와 실시간 채팅을 결합하여, 매칭된 유저가 채팅방에서 사진을 주고받을 수 있도록 구현할 계획입니다.
읽지 않은 알림 및 메시지 : 읽지 않은 알림과 메시지의 개수를 유저에게 표시하여 좀 더 나은 서비스 경험을 제공할 계획입니다.
성능 개선 과제
유저 피드백으로 페이지 로드와 페이지 사이에서 넘어갈 때 느리다는 의견을 받았고, 저희도 문제를 인식하고 있었습니다.
해결 방법
서비스 특성상 자주 호출되는 API는 매칭 상대 조회입니다. 많은 유저 데이터를 조회해야 하므로, API를 처음 호출할 때 조회한 데이터를 Redis에 저장하고, 이후 요청 시 Redis를 먼저 확인하여 데이터가 있으면 Redis에서 가져오고, 없으면 DB를 조회한 후 Redis에 저장하는 방식을 사용한다면 불필요한 API 호출을 줄이고 속도를 개선할 수 있을 것입니다.
현재는 좋아요/싫어요 API를 호출한 뒤 매칭 상대 조회 API를 다시 호출하고 있습니다. 그러나 이미 가져온 10명의 매칭 상대를 프론트에서 배열로 임시 저장해두고, 좋아요/싫어요 시 해당 매칭 상대를 배열에서 삭제한 후 다음 상대를 보여주는 방식으로 수정하면 서비스 속도를 크게 개선할 수 있을 것입니다.
현재 채팅 메시지가 전송될 때마다 데이터베이스에 직접 저장하는 방식을 사용하고 있습니다. 이를 채팅 중에는 Redis를 사용해 메시지를 인메모리에 저장하고, 필요한 시점에만 MySQL에 저장하는 방식을 도입해 성능을 최적화할 계획입니다.
현재는 좋아요/싫어요 API를 호출한 뒤 매칭 상대 조회 API를 다시 호출하고 있습니다. 그러나 이미 가져온 10명의 매칭 상대를 프론트에서 배열로 임시 저장해두고, 좋아요/싫어요 시 해당 매칭 상대를 배열에서 삭제한 후 다음 상대를 보여주는 방식으로 수정하면 서비스 속도를 크게 개선할 수 있을 것입니다.
현재 채팅 메시지가 전송될 때마다 데이터베이스에 직접 저장하는 방식을 사용하고 있습니다. 이를 채팅 중에는 Redis를 사용해 메시지를 인메모리에 저장하고, 필요한 시점에만 MySQL에 저장하는 방식을 도입해 성능을 최적화할 계획입니다.