SHOOTOCK

SHOOTOCK

빠르고 직관적으로 실시간 주식 데이터 조회를 제공하는 웹 서비스

1. Overview

SHOOTOCK 은 한국투자증권 Open API를 이용하여 페이지 새로고침 없이 실시간으로 주식 데이터를 제공하는 서비스입니다. 프론트엔드는 React와 브라우저 WebSocket API를 사용하였고, 백엔드는 Spring Boot 기반으로 Kafka와 Redis를 활용하여 구성하였습니다. 서비스는 AWS의 EKS 환경에 배포하였습니다.


SHOOTOCK Architecture

Architecture Diagram of EKS Cluster & CI/CD for SHOOTOCK

이 아키텍처가 제공하는 주요 효과는 다음과 같습니다.

  • 실시간성: WebSocket과 Kafka를 활용한 데이터 파이프라인을 통해 실시간 주식 시세를 전송합니다.
  • 고가용성: RDS Multi AZ 구성을 통해 하나의 AZ 장애 시에도 서비스의 연속성을 보장합니다.
  • 확장성: EKS 관리형 노드 그룹에 오토스케일링 범위(desired 2, max 3)를 두고 부하 시 노드가 늘어나는 것을 CloudWatch와 Grafana로 확인했습니다. 파드는 프론트/백엔드 각 3개 복제본으로 고정 운영했습니다. RDS Storage Auto Scaling으로 여유 공간이 임계치 아래로 떨어지면 스토리지가 자동 확장되도록 구성했습니다.


2. My Role

개발 기간인원담당 영역(기여도 60%)
2024-12 ~ 2025-03 (3 개월)5명UI/UX, 실시간 스트리밍 데이터 파이프라인, IaC/CI/CD, Security
  • UI/UX
    • WebSocket 재연결 로직 구현 및 Context API를 활용한 전역 상태 관리
  • Data Pipeline
    • Kafka 및 Redis를 이용한 실시간 데이터 파이프라인 구축
  • IaC
    • Terraform을 이용한 AWS 인프라 자동화 및 관리
  • CI/CD
    • Github Actions 및 ArgoCD 기반의 EKS 자동 배포 환경 구축
  • Security
    • AWS Secrets Manager, IAM, OIDC를 이용한 민감 정보 보호 및 접근 제어 관리


3. Problem Statement

초기 프로토타입은 브라우저 → WebSocket API 직결 구조였습니다. 하지만 다음 문제에 직면했습니다.

  • 데이터 정규화 부재: 종목마다 필드가 상이해 클라이언트 코드가 복잡해졌습니다. 또한 종목 별 메시지 순서가 보장이 되지 않아 가격과 거래량이 일치하지 않는 상황이 발생했습니다.

  • 데이터 누락: 네트워크 지연이나 웹소켓의 끊김으로 인해 데이터가 손실되었으며, 브라우저 새로고침 시 과거 데이터를 유지할 수 없었습니다.

이 문제를 해결하기 위해 중앙 데이터 파이프라인을 구축하고 데이터 정규화 및 복구 로직을 도입했습니다.

4. Methods

Data Pipeline

SHOOTOCK Architecture 실시간 주식 체결 데이터를 위한 데이터 파이프라인

한국투자증권에서 실시간 주식 데이터를 WebSocket으로 받아옵니다. 해당 데이터를 정규화한 뒤 종목별 Topic (realtime-data-{stockId})으로 Publish 합니다. Consumer는 topicPattern = "realtime-data-.*"로 전 종목을 구독해, 한쪽은 접속 중인 브라우저 세션 전체에 WebSocket Broadcast로 전달하고, 한쪽은 Redis 리스트에 leftPush 후 trim(0, 4)로 종목당 최근 5건만 유지합니다. 직전 메시지와 내용이 같으면 저장하지 않아 중복을 걸러냅니다.

  • 데이터 정규화: 클라이언트 측 부하를 줄이고, 카프카의 토픽 별 순서 보장을 통해 종목 데이터의 정합성을 확보했습니다.
  • 데이터 누락 방지: 브라우저 WebSocket이 끊기면 클라이언트가 일정 시간 뒤 자동 재연결하고, 그동안의 최근 데이터는 Redis에서 받아 화면을 이어갑니다.

5. Troubleshooting

5-1. Extended Outage from RDS Single-AZ Failure

Single AZ 환경에서는 RDS 장애 시 자동 Failover가 제공되지 않아, 장애 발생 시 약 9분 이상의 서비스 중단이 발생하였습니다. 이를 해결하기 위해 RDS를 Multi AZ로 전환하여 장애 발생 시 자동 Failover가 이루어지도록 구성했고, 실제 서비스 중단 시간을 9분 29초에서 약 25초로, 약 96% 줄였습니다.

인프라 유형서비스 중단 시간검증 및 테스트 (영상)
Single AZ RDS9분 29초Single AZ
Multi AZ RDS25초Multi AZ

5-2. SecretProviderClass Failing to Create Secrets

AWS Secrets Manager와 EKS의 Secrets Store CSI Driver를 이용하여 동적으로 Secret을 생성하는 과정에서 문제가 발생했습니다.

SecretProvider

EKS Pod의 Secrets 동적 생성을 위한 Secret 아키텍처 다이어그램

  • RBAC 권한 문제 해결
    • Secrets Store CSI Driver의 Log를 통해 ClusterRole에 Secret 관련 list 권한이 없는 문제를 확인하였습니다.
      failed to list *v1.Secret: secrets is forbidden: User \"system:serviceaccount:kube-system:secrets-store-csi-driver\" cannot list resource \"secrets\" in API group \"\" at the cluster scope\n"
      
    • ClusterRole에 List 권한을 추가해주고, ClusterRoleBinding에 CSI Driver의 Service Account를 추가해주었습니다.
  • Secret 동기화 활성화
    • Helm Chart 옵션에서 syncSecret.enabled=true 로 활성화시켜주어 Secret 동적 생성을 활성화했습니다.

6. Future Works

  • API 세션의 한계: 현재 한국투자증권 API는 계정당 동시 1세션, 최대 20종목만 구독 가능한 한계를 가지고 있습니다. 현재 인기 상위 30종목을 제공하지만 실제로는 20종목만 실시간 데이터가 가능하고, 나머지 종목은 Latency가 발생합니다. 향후 여러 계정을 활용하여 Producer Pool을 늘리고 더 많은 종목을 실시간으로 제공할 계획입니다.

  • 모니터링: 프로젝트 기간 동안 CloudWatch 및 Grafana를 이용하여 Auto Scaling 동작만 확인했습니다. 향후 Prometheus를 활용하여 API Latency, CPU, 메모리 사용량 등 주요 지표를 세부적으로 모니터링하고 장애 대응 속도를 높일 계획입니다.

7. Used Skills

  • AWS EKS
  • Kubernetes
  • ArgoCD
  • Helm
  • Terraform
  • Kafka
  • Redis
  • React
  • Spring Boot
  • GitHub Actions
  • AWS Secrets Manager
  • RDS