Skip to content

Latest commit

 

History

History
286 lines (205 loc) · 12.9 KB

README.md

File metadata and controls

286 lines (205 loc) · 12.9 KB

실시간 날씨 정보와 AI가 결합된 새로운 날씨 플랫폼, WeatherWise


🔖 프로젝트 개요

주제: 사용자 맞춤형 날씨 정보 제공 및 상호작용 플랫폼
대상: 날씨 정보 활용 및 상호작용에 관심이 있는 사용자


🎯 목표

  1. 정확한 날씨 정보 제공: 기상청 데이터와 AI 분석을 통해 지역별 맞춤형 날씨 정보 전달
  2. 미션 수행과 커뮤니티 강화: 날씨 기반 미션과 커뮤니티 상호작용을 통해 사용자 참여 유도
  3. 긴급 상황 대응: 기상특보 채팅으로 실시간 정보 공유 및 대응

📚 기술 스택

Frontend

  • ⚛️ React: 사용자 인터페이스(UI) 개발을 위한 라이브러리

Backend

  • 🌱 Spring Boot: 강력한 백엔드 애플리케이션 개발 프레임워크
  • 🐬 MySQL: 데이터 저장 및 관리에 사용된 관계형 데이터베이스
  • 🚀 Redis: 캐싱 및 실시간 데이터 저장
  • 💬 Kafka: 메시지 큐 및 데이터 스트리밍 도구로 실시간 채팅 및 알림 구현

DevOps / Infrastructure

  • 🛠️ Jenkins: CI/CD 자동화를 위한 도구
  • 📦 Docker: 애플리케이션 컨테이너화
  • ☸️ Kubernetes: 컨테이너 오케스트레이션 및 관리
  • 🐙 Argo: DevOps 워크플로우 관리
  • ☁️ AWS: 클라우드 인프라 호스팅
  • 🔀 Nginx: 리버스 프록시 및 웹 서버

AI / Automation

  • 🐍 Python: 데이터 처리 및 AI 모델 개발
  • 🔗 LangChain: AI 어플리케이션 구축을 위한 프레임워크

Collaboration / Tools

  • 🐙 GitHub: 버전 관리 및 소스 코드 관리
  • 📝 Notion: 프로젝트 관리 및 문서화
  • 🎮 Discord: 팀 커뮤니케이션
  • 🎨 Figma: UI/UX 디자인

🔗 주요 기능

1️⃣ 회원 및 인증 관리 시스템

  • JWT 기반 사용자 인증

    • 사용자 로그인/회원가입 시 JWT 토큰 발급 및 인증 관리.
    • STOMP 헤더에 JWT 토큰을 포함해 실시간 채팅에서도 인증 처리.
    • 토큰에서 사용자 ID를 추출하여 커뮤니티, 미션 등 다양한 기능에 활용.
  • 회원가입 및 로그인

    • 일반 회원가입 및 카카오 소셜 로그인 지원.
    • 비밀번호 검증 및 닉네임 중복 방지 처리.
  • 사용자 정보 관리

    • 사용자 정보 수정, 닉네임 변경, 로그아웃 및 회원 탈퇴 기능 제공.

2️⃣ 미션 생성 및 인증

  • 날씨 기반 맞춤형 미션 제공

    • 기상 데이터를 활용하여 아침, 점심, 저녁 기준으로 최대 3개의 미션 생성.
    • 예시 미션: "자전거를 타세요", "텀블러를 사용하세요".
    • 각 미션마다 포인트 지급률 및 진행 상태 표시.
  • AI 기반 미션 인증

    • 사용자가 미션에 맞는 사진을 첨부하면 AI가 해당 사진의 적합성을 검증.
    • 인증 성공 시 포인트 지급 및 실패 시 재도전 가능.
  • 포인트 및 랭킹 시스템

    • 포인트를 기반으로 사용자 랭킹 제공.
    • 순위 확인 및 검색 기능을 통해 사용자 경험 향상.

3️⃣ 커뮤니티

  • 위치 기반 게시글

    • 사용자의 현재 위치를 기준으로 반경 5km 내 게시글 표시.
    • 위치 변경 시 카카오맵 API를 통해 새로운 위치 반영 및 게시글 업데이트.
  • 게시글 작성

    • 제목(20자) 및 본문(150자) 글자 수 제한을 통해 사용자 경험 최적화.
    • 좋아요/싫어요 버튼으로 게시글 신뢰도 평가 가능.
  • 내가 작성한 글 관리

    • 사용자가 작성한 글의 리스트를 확인 및 삭제 가능.

4️⃣ 기상특보 오픈채팅

  • 기상특보에 따른 실시간 채팅방 생성
    • 기상특보 발생 시 해당 지역의 사용자들을 위한 오픈 채팅방 자동 생성.
    • 예: "강원도 건조/한파 경보 채팅방".
  • 기상특보 데이터 업데이트:
    • Spring Scheduler를 활용해 1시간마다 기상청 API 호출.
    • 기상특보 발령 시 '시/도' 기준으로 실시간 단체 오픈채팅방 자동 생성.
  • 실시간 채팅:
    • Redis:
      • 최신 채팅 메시지 100개를 캐싱하여 빠른 채팅 로드 제공.
      • 사용자 간 실시간 메시지 교환 성능 향상.
    • WebSocket + STOMP:
      • 실시간 양방향 통신 구현.
      • 채팅방 내 메시지 브로드캐스팅 및 실시간 알림 기능 제공.
  • WebFlux와 R2DBC를 활용한 확장:
    • WeatherWise-Server-Chatting 레포지토리에서 MSA 구조로 구현.
    • WebFlux와 R2DBC를 사용해 비동기 처리로 확장성과 성능 향상.

🌈 개선 사항

1️⃣ 채팅 성능 개선 - 최대 트래픽 처리량 약 4배 증가


문제 상황

  • 기존 모놀리식 구조에서는 Spring MVC를 사용하여 초당 최대 400명의 사용자 요청을 처리했으나, 이 이상의 트래픽이 발생하면 서버가 과부하로 인해 다운되는 문제가 발생.
  • 응답 속도가 느려지고 데이터의 정합성에도 문제가 생길 가능성이 높아짐.

1. MSA 도입과 WebFlux 전환

  • 채팅 기능을 독립적인 MSA 서비스로 분리하여 Spring WebFlux를 도입.
  • WebFlux의 비동기/논블로킹 특성을 활용해 높은 동시 처리 성능 확보.
    • 기존 Servlet 기반의 동기 요청-응답 처리 방식에서 WebFlux 기반의 비동기 논블로킹 방식으로 전환
    • 다수의 동시 연결 요청을 처리할 수 있는 확장성 확보
    • WebFlux를 적용함으로써 이벤트 루프 기반의 효율적인 리소스 사용으로 응답 시간이 단축됨
  • Kafka를 사용하여 메시지 큐 기반의 비동기 통신을 적용, 서비스 간 결합도를 낮추고 안정성 강화.
    • 메시지 송수신에서 발생하던 I/O 병목 현상을 완화하기 위해 Kafka를 메시지 브로커로 활용
    • WebSocket으로 수신된 메시지를 Kafka Producer로 처리해 분산 브로커에 저장
    • Kafka Consumer가 메시지를 Redis에 저장하고, 채팅방 사용자에게 전달
    • Kafka를 통해 메시지 큐를 관리함으로써 부하를 분산 처리하고 데이터 손실을 방지
    • WebSocket에서 직접 Redis와 연결하는 대신 Kafka를 중간 계층으로 사용해 안정성과 성능 향상
  • Redis 캐싱 최적화
    • Redis를 사용해 채팅방의 최신 메시지 100개를 캐싱
    • 사용자 요청 시 Redis에서 즉시 데이터를 제공해 응답 속도 향상
    • 기존 Redis 저장 방식에서 동시성 이슈를 해결하기 위해 락(lock) 메커니즘 적용
  • R2DBC로 데이터베이스 성능 개선
    • R2DBC를 도입해 MySQL 데이터베이스와의 통신을 비동기 방식으로 전환
    • 기존의 동기 JPA 접근 방식에서 발생하던 I/O 대기 시간을 줄여, 채팅 데이터 저장 시 처리 속도 개선
    • 트랜잭션 처리가 간단한 채팅 시스템에 적합한 경량 데이터 처리 방식으로 전환

2. 데이터 정합성 보장

  • WebFlux와 Kafka를 통해 대량의 데이터를 처리하면서도 4만 건 이상의 데이터 정합성을 100% 유지.
  • 데이터 손실 없이 모든 메시지가 안정적으로 DB에 저장되도록 설계.

결과

  • 처리량 증가: 초당 400명 → 1500명 이상의 사용자 요청 처리 가능.
  • 응답 시간 단축: 평균 응답 시간 80% 이상 감소.
  • 데이터 정합성: 100% 데이터 일치 보장.
  • 다수의 동시 연결 환경에서도 메시지 손실 없이 실시간 채팅 가능.

image

2️⃣ 선착순 쿠폰 이벤트 (모놀리식 → MSA 마이그레이션)

기존 모놀리식 아키텍처 에서 마이크로서비스 아키텍처(MSA) 로 전환하는 과정을 설명합니다.
특히, 쿠폰 발급 서비스의 성능 문제를 해결하기 위해 Kafka를 활용한 비동기 메시지 처리 방식으로 전환한 사례를 중심으로 다룹니다.


🚨 모놀리식 아키텍처의 문제점

쿠폰 이벤트

  • 특정 프로모션을 통해 사용자에게 쿠폰을 발급하는 이벤트입니다.
  • 아래 발급 조건을 충족해야 쿠폰을 받을 수 있습니다.

쿠폰 발급 조건

  1. 한 사람당 한 개의 쿠폰만 가질 수 있다.
  2. 당일 미션 하나를 인증 받아야 한다.
  3. 이벤트 기간 동안, 매일 특정 시간에 오픈하며 총 지급 수량을 한정한다.
  4. 쿠폰 지급 수량은 당일 정해진 양을 초과할 수 없다.

🚧 트래픽 몰림 시 문제점

모놀리식 아키텍처는 모든 기능이 단일 서비스 내에 통합되어 있어 아래와 같은 문제가 발생했습니다:

  • 서버 마비: 트래픽이 급증하면 서버 자원이 고갈되어 기본 기능(예: 회원가입, 로그인)조차 정상적으로 작동하지 않음.
  • TPS 한계: 평균 TPS 200에 도달 시 웹서버가 병목현상을 일으키며, 전체 서비스가 중단.

🔧 MSA 도입 배경

모놀리식 구조의 한계를 극복하고, 높은 트래픽 상황에서도 안정적인 서비스를 제공하기 위해 MSA를 도입했습니다.

  • 각 기능을 독립적인 마이크로서비스로 분리.
  • 특정 서비스 장애가 전체 시스템에 영향을 미치지 않도록 설계 가능.

⚙️ MSA 도입 과정

1️⃣ 서비스 분리 및 HTTP 동기 방식 문제

  • 초기에는 서비스 간 통신 방식으로 가장 익숙한 HTTP를 사용.
  • 그러나 HTTP는 동기 요청 방식이기 때문에 모놀리식의 한계(서비스 간 결합도)와 장애 전파 문제를 해결하지 못함.

2️⃣ Kafka를 활용한 EDA로 전환

도입 배경

  • 기존 HTTP 요청 방식의 결합도 높음장애 전파 위험을 해결하기 위해 Kafka를 도입.
  • Kafka를 통해 비동기 메시지 기반 아키텍처로 전환.

Kafka 도입 이유

  1. 비동기 처리
    • 메시지를 큐에 저장하여 서비스 간 비동기적으로 데이터를 처리.
  2. 내결함성
    • 메시지가 큐에 저장되므로 특정 서비스가 다운되더라도 메시지가 유지됨.
    • 서비스 복구 후 메시지 재처리 가능.
  3. 높은 처리량
    • Kafka는 높은 스루풋을 지원해 대량의 메시지를 효율적으로 처리.
  4. 확장성
    • 메시지 브로커를 통해 서비스 간 결합도를 낮춰, 각 서비스를 독립적으로 확장 가능.

🛠️ 비동기 방식의 장점

  1. 서비스 독립성 강화
    • 서비스 간 직접적인 의존성을 제거하고, 메시지 브로커를 통한 간접적 통신으로 독립성 강화.
  2. 유연한 에러 처리
    • 장애 발생 시 메시지를 큐에 저장하여 재처리하거나 다양한 방식으로 에러 처리 가능.
  3. 성능 향상
    • 비동기 메시지 처리로 블로킹 없이 다수의 요청을 처리해 전체 시스템 성능 개선.

✅ 전환 후 성과

Kafka 기반 비동기 메시지 처리로 다음과 같은 성과를 달성했습니다:

  1. 성능 개선
    • 트래픽 폭주 상황에서도 서비스 마비 없이 안정적 동작.
  2. 신뢰성 향상
    • 서비스 다운 시에도 메시지가 큐에 저장되어 복구 후 처리가 가능.
  3. 확장성 강화
    • 각 서비스를 독립적으로 스케일링 가능해 전체 시스템 유연성 증가.
  4. 데이터 정합성 유지
    • 비동기 메시지 처리로 데이터 정합성을 유지하며, 고트래픽 상황에서도 안정적 데이터 처리 가능.

결론

모놀리식 아키텍처에서 MSA로의 전환은 초기에는 복잡해 보일 수 있습니다. 그러나 높은 트래픽과 장애 상황에서 문제를 효과적으로 해결할 수 있는 강력한 방법입니다.

Kafka를 활용한 비동기 메시지 처리는:

  • 서비스 간 결합도를 낮추고,
  • 시스템 신뢰성과 확장성을 향상시키며,
  • 안정적인 사용자 경험을 제공합니다.

이러한 전환을 통해 서비스 간 독립성을 확보하고, 높은 트래픽 상황에서도 확장성과 안정성을 겸비한 아키텍처를 구현할 수 있었습니다.

아키텍처별 성능 비교

아키텍처별 성능 비교



MSA 전환한 Git Repository


🚀 트러블 슈팅

1️⃣ 추가

👨‍💻 팀원

  • Frontend Developer: 박설, 김지원
  • Backend Developer: 박설, 김지원