경제 시뮬레이션 웹 게임. 유저가 회사를 운영하며 시장에서 아이템을 거래하고, 실시간 호가/체결에 따라 시가총액 랭킹이 갱신되는 서비스.
- 실시간 호가창 기반 아이템 매수/매도 및 체결
- 작업장(생산), 창고(재고), 인력소, 은행 등 회사 운영 요소
- Google OAuth 소셜 로그인 + 게스트 로그인(회원가입 없이 체험 후 계정 승격)
- 외부 지표(금, 금리, 뉴스)를 반영한 시장 이벤트
- 시가총액 기반 실시간 랭킹
- 3D Isometric 뷰 기반 게임 화면
Backend
- Spring Boot (Java), Spring Security, Spring Data JPA
- JWT + OAuth2 (Google)
- WebSocket (STOMP)
Frontend
- React, TypeScript, Vite
- Three.js 기반 3D 렌더링, Tailwind CSS, shadcn/ui
- Zustand
Data / Infra
- PostgreSQL (OLTP / OLAP)
- Redis (캐시 · 실시간 상태)
- Kafka (이벤트 스트리밍)
- Spark, HDFS (배치/스트리밍 집계, 데이터 레이크)
- Docker Compose, Kubernetes, Jenkins
- Nginx, Prometheus/Grafana
Test
- k6 (부하 테스트)
세부 데이터 흐름은 bigdata/README.md, 프론트 구조는 frontend/architecture.md 참고.
최초 상태: 프론트가 3초마다 REST API 폴링 → 호가 변동이 최대 3초 후 반영, 사용자 수가 늘수록 서버 요청이 선형으로 증가.
| Step | 문제 | 해결 | 결과 |
|---|---|---|---|
| 1 | REST API N+1 (호가 500건마다 Redis HGETALL) |
스케줄러가 300ms마다 스냅샷 계산 → API는 Redis 1-GET으로 응답 | p95 700ms → 수ms |
| 2 | 체결 여부 무관하게 300ms마다 재계산 | 체결 시에만 dirty=true 마킹 후 재계산(Dirty Flag) |
무조건 초당 3회 실행 → 체결 시에만 실행 |
| 3 | 3초 폴링으로 인한 반영 지연 | REST 폴링 제거, STOMP WebSocket Push로 전환 | 반영 지연 3,000ms → 즉시 |
| 4 | 매칭 단일 스레드 순차 처리 → WS 연결 실패율 43.98% | 아이템별 전용 스레드로 병렬 처리 | 연결 실패율 43.98% → 0% |
| 5 | 봇 주문이 Kafka 경유하며 2~8초 지연 | 봇 주문 한정 Kafka 우회, Redis 직접 쓰기 | 반영 지연 2~8초 → ~1ms |
| 6 | 무체결 구간 화면 Frozen | 500ms 주기 Force Push 추가 | Frozen 구간 최대 500ms로 상한 보장 |
| 7 | 스케줄러 내부 N+1 (초당 Redis 요청 ~6,000회) | executePipelined + HMGET으로 일괄 조회 |
Redis 왕복 1,000회 → 1회 (초당 ~6,000회 → ~6회) |
결과: 3초 간격 폴링 → 500ms 이내 부드러운 실시간 Push.
각 Step의 원인 분석·코드는 Technical Issue 위키 페이지 참고.
docker network create ecosim-network각 모듈의 .env 파일 준비 (backend/.env, data/.env, infra/.env 등). 필요한 환경변수 목록은 exec/readme.md 참고.
docker compose -f docker-compose.yaml up -d --builddocker compose -f docker-compose.yaml ps
docker compose -f docker-compose.yaml down# Backend
cd backend && ./gradlew bootRun
# Frontend
cd frontend && npm install && npm run devk6 기반 부하 테스트를 제공한다. 자세한 실행 방법과 임계값은 k6-tests/README.md 참고.
cd k6-tests
k6 run tests/orderbook-smoke.js # 기본 동작 확인
k6 run tests/orderbook-load.js # 예상 트래픽 (VU 20명, 5분)
k6 run tests/orderbook-stress.js # 한계 탐색 (VU 최대 200명)| 이름 | 역할 |
|---|---|
| 최두용 | BE / INF / 팀장 |
| 강찬휘 | BE |
| 김은수 | DE |
| 소재헌 | DE |
| 손서영 | FE |
| 허서연 | FE |

