Backend Developer

Backend & DevOps Engineer

Java / Spring Boot 기반 백엔드 설계부터 k3s 온프레미스 인프라 운영, AI 데이터 파이프라인 구축까지 — 아이디어를 프로덕션으로 연결합니다.


01

기술 스택

Backend
Java 21Spring Boot Spring Data JPAQueryDSL Spring SecurityJWTRedisFlyway
Database
PostgreSQLMySQLRedisH2PostGIS
DevOps / Infra
DockerKubernetes (k3s) GitHub Actionsingress-nginxcert-managerNAS
Monitoring
GrafanaPrometheus LokiTempoOpenTelemetry

02

역량 기술서

01
백엔드 설계 및 개발 역량
Java 21과 Spring Boot 기반의 RESTful API 서버 설계 및 개발 경험이 있습니다. 헥사고날 아키텍처(Ports & Adapters)를 적용하여 Domain 레이어에서 프레임워크 의존성을 완전히 제거하고, UseCase / LoadXxxPort / SaveXxxPort 인터페이스 분리를 통해 DB 없이 Mock만으로 서비스 레이어를 검증할 수 있는 단위 테스트 구조를 설계했습니다. Spring Data JPA와 QueryDSL을 활용한 타입 안전한 데이터 접근 계층, DTO 패턴 기반 도메인과 API 계층 분리, JPA @Version Optimistic Lock을 통한 동시성 제어도 구현한 경험이 있습니다.
02
인증 및 보안 시스템 구축
Spring Security 기반 인증 구조를 설계하고 JWT와 Redis를 활용한 토큰 인증 시스템을 구현했습니다. Redis MULTI/EXEC를 활용한 원자적 토큰 교체로 1인 1세션 정책을 구현했으며, IP·계정 이중 레이트 리미팅으로 브루트포스 공격에 대응했습니다. OAuth2.0 Google 로그인을 적용하여 웹과 앱을 모두 고려한 멀티 플랫폼 인증 아키텍처를 구성했습니다.
03
성능 최적화 경험
PostGIS 공간 인덱스와 캐싱 전략을 적용하여 위치 기반 조회 성능을 1393ms에서 6ms 수준으로 약 232배 개선했습니다. 업로드 로직에 비동기 처리를 도입하여 처리 속도를 약 3.3배 향상시켰습니다. AI 파이프라인에서는 asyncio 기반 비동기 DNS 전환으로 처리 속도를 17배 저하에서 정상 복구(12개/분 → 35개/분)시켰으며, LLM 모델 최적화(qwen3:14b → qwen3:8b)를 통해 영상 처리 속도를 6배(4분 → 39초) 향상시킨 경험이 있습니다.
04
DevOps 및 인프라 운영
개인 서버에 k3s 온프레미스 클러스터를 직접 구축하여 PostgreSQL StatefulSet과 Redis Deployment를 운영하고 있습니다. ingress-nginx 기반 리버스 프록시와 cert-manager를 통한 SSL 자동화, 불필요한 NodePort 노출 제거 등 보안 강화 작업을 수행했습니다. GitHub Actions 기반 3단계 CI/CD 파이프라인(코드 push → 단위 테스트 → Docker 이미지 빌드 → ghcr.io 푸시 → SSH 롤링 배포)을 구축했으며, SHA 기반 이미지 태깅으로 즉각적인 롤백 구조를 설계했습니다.
05
관측성(Observability) 및 운영 자동화
Grafana + Prometheus(메트릭) + Loki(로그) + Tempo(트레이싱) + OpenTelemetry Collector를 통합한 Full-Stack Observability 환경을 구성했습니다. Shell 스크립트와 crontab을 활용하여 PostgreSQL pg_dump, PVC rsync, Grafana 대시보드 백업을 자동화하고 NAS로 매일 전송하는 운영 환경을 구축했습니다.
06
AI / 데이터 파이프라인 개발
Python 3.12와 asyncio 기반으로 YouTube STT(Whisper)와 웹 크롤링 이중 채널을 결합한 대규모 데이터 수집 파이프라인을 설계·개발했습니다. Ollama LLM(qwen3)을 활용하여 비구조 텍스트에서 구조화된 JSON 데이터를 자동 파싱하며, 10,150개 대학의 교환학생 정보를 처리했습니다. JSONL 체크포인트 + Atomic 파일 저장으로 중단 없는 재시작 구조를 설계하고, Watchdog 스크립트와 Rich 라이브러리 기반 실시간 모니터링 대시보드도 구현했습니다.

03

프로젝트

Ovlo — 교환학생 커뮤니티 플랫폼
2026.01 ~ 현재 (진행 중) · 개인 프로젝트
Java 21Spring Boot Hexagonal Archk3s GitHub ActionsGrafana Stack
Java 21 + Spring Boot 기반 교환학생 커뮤니티 플랫폼. TDD + 헥사고날 아키텍처로 8개 Bounded Context를 구현하고, k3s 온프레미스 서버에 완전 자동화된 파이프라인으로 배포 및 운영 중.
백엔드 아키텍처
헥사고날 아키텍처: Domain에서 프레임워크 의존성 완전 제거. UseCase / LoadXxxPort / SaveXxxPort 분리로 DB 없이 Mock만으로 단위 테스트
동시성 제어: JPA @Version Optimistic Lock으로 좋아요/싫어요 Lost Update 방지. Redis INCR 교체 로드맵 설계
JWT + Redis: Access 15분 / Refresh 7일. MULTI/EXEC 원자적 토큰 교체로 1인 1세션. IP·계정 이중 레이트 리미팅
스토리지 추상화: StoragePort로 Local → S3 무중단 교체 설계. HEIC → JPEG 자동 변환
DevOps / 인프라
온프레미스 k3s: Lenovo 서버에 멀티노드 직접 구성. Deployment, PVC, Service, Ingress, Health Probe 전체 직접 작성
네트워크 보안: ingress-nginx + cert-manager SSL 자동화. NodePort 제거 및 Traefik 비활성화
CI/CD: push → 테스트 → 빌드 → ghcr.io(SHA 태그) → SSH 롤링 배포 3단계. ImagePullBackOff 트러블슈팅 해결
모니터링 & 운영
Observability: Grafana + Prometheus + Loki + Tempo + OTel 통합. v10 alerting 엔진 변경 DatasourceError → Provisioning API 직접 해결
자동 백업: pg_dump + rsync + Grafana API Shell 통합. crontab 03:00 NAS 전송, 30일 보관
Architecture Diagram · Ovlo
Ovlo — 교환학생 커뮤니티 플랫폼 Hexagonal / Ports & Adapters Java 21 · Spring Boot 4.0
Adapter — IN
REST Controllers
MemberApiController AuthApiController UniversityApiController BoardApiController PostApiController FollowApiController MediaApiController ChatApiController ExchangeUnivController
WebSocket
STOMP over WS JwtChannelInterceptor Chat Handler
@Valid 요청 검증
21개 Request DTO Jakarta Validation
UseCase 호출
Application Layer
Port · IN
MemberUseCase AuthUseCase PostUseCase BoardUseCase ChatUseCase MediaUseCase FollowUseCase
Query Port · IN
PostQueryUseCase BoardQueryUseCase UnivQueryUseCase
Command Services
MemberCommandService AuthCommandService PostCommandService BoardCommandService ChatCommandService MediaCommandService FollowCommandService
Query Services
PostQueryService BoardQueryService UniversityQueryService ChatQueryService ExchangeUnivQueryService
Port · OUT
LoadMemberPort SaveMemberPort LoadPostPort SavePostPort LoadBoardPort TokenStorePort StoragePort
Command DTO (순수 record)
RegisterMemberCommand CreatePostCommand CreateBoardCommand
Result DTO
MemberResult PostResult PageResult<T>
도메인 불변식
Domain (순수 Java)
member
Email · Password · MajorLanguageSkill VO
auth
TokenPair · AuthSession
university
University · ExchangeUnivCountryCode · VideoReview
board
Board · BoardSubscription
post
Post · Comment · Reaction@Version (동시성)
follow
Follow
media
MediaFile · StoragePath
chat
ChatRoom · MessageReadMarker
Port 구현체
Adapter — OUT
JPA Persistence
MemberPersistenceAdapter PostPersistenceAdapter BoardPersistenceAdapter ChatPersistenceAdapter PostgreSQL 16 Flyway V1~V11
Redis Adapter
RedisTokenAdapter TokenStorePort 구현 MULTI/EXEC 원자적 교체
Storage Adapter
LocalStorageAdapter S3StorageAdapter (Phase 2) HEIC→JPEG 변환
adapter/in → application/port/in → domain
adapter/out ← application/port/out ← domain
domain → application (역방향 금지)
service → JpaRepository 직접 주입 금지
domain 에 @Entity, @Service 금지
Architecture Diagram · SnapGuide & TimeManager
아키텍처 비교 Layered vs Hexagonal
📸 SnapGuide Layered Architecture Java 17 · Spring Boot 3.4

① Controller Layer — REST API 진입점
AuthController
GuideController
LocationController
MediaController
MemberController
PushController
@Valid 요청 검증 · SpringDoc OpenAPI · CORS Config
DTO 변환
② Service Layer — 비즈니스 로직
GuideService
MediaService
MemberService
LocationService
GoogleOAuthService
PushService
FileStorageService
@Transactional · @Version Optimistic Lock · 비동기 미디어 처리
JPA 직접 의존
③ Repository Layer — 데이터 접근
GuideRepository
MediaRepository
MemberRepository
LocationRepository
GuideLikeRepository
Spring Data JPA · QueryDSL 5 · PostGIS 공간 인덱스
④ Infrastructure — 외부 시스템 연동
PostgreSQL + PostGIS
Redis (캐시 · 세션)
S3 / Local Storage
Google Maps API
JWT + OAuth2
Web Push VAPID
OTEL + Grafana
⏱ TimeManager Hexagonal Architecture Java 17 · Spring Boot 3.4

Adapter · IN — REST Controllers
AuthApiController
MemberApiController
RecordApiController
TagApiController
NotificationApiController
@Valid 검증 · JwtAuthenticationFilter
Port/In (UseCase 인터페이스)
Application Layer — Services & Ports
AuthCommandService
TagCommandService
RecordCommandService
TagQueryService
RecordQueryService
NotificationService
Port/In (UseCase · Query) · Port/Out (LoadXxxPort · SaveXxxPort)
Domain 순수 Java
Domain Layer — 순수 Java (프레임워크 금지)
Tag (계층형 트리)
Record (TimeRange VO)
Member
AuthSession
Notification
create() 팩토리 · restore() (영속성 전용) · 자동 시간 집계
Port/Out 구현 (JPA Adapter)
Adapter · OUT — Persistence & External
TagPersistenceAdapter
RecordPersistenceAdapter
MemberPersistenceAdapter
RedisTokenAdapter
PostgreSQL / H2
JPA Entity ↔ Domain Model 변환 (Mapper) · 단일 타이머 정책
API Design Structure · 전체 프로젝트
REST API 엔드포인트 설계 Ovlo · SnapGuide · TimeManager
9 OVLO CONTROLLERS
6 SNAPGUIDE CONTROLLERS
5 TIMEMANAGER CONTROLLERS
40+ TOTAL ENDPOINTS
21 OVLO REQUEST DTOs
2 WEBSOCKET CHANNELS
HTTP METHODS:
GET조회
POST생성
PUT전체 수정
PATCH부분 수정
DELETE삭제
🌐 Ovlo
HEXAGONAL · Java 21 · Spring Boot 4.0.3 · PostgreSQL 16 + Redis 7
👤 Member/api/members
POST/register회원가입
PATCH/profile프로필 수정
GET/search닉네임 검색
DELETE/me회원 탈퇴
🔐 Auth/api/auth
POST/login로그인
POST/refresh토큰 갱신
POST/logout로그아웃
🏫 University/api/universities
GET/search키워드 검색
GET/exchange교환대학 목록
GET/exchange/{id}상세 + 영상리뷰
📋 Board/api/boards
POST/게시판 생성
GET/게시판 목록
POST/{id}/subscribe구독
📝 Post/api/posts
POST/게시글 작성
GET/{id}게시글 조회
PATCH/{id}게시글 수정
DELETE/{id}게시글 삭제
POST/{id}/comments댓글 작성
POST/{id}/react좋아요/싫어요
👥 Follow/api/follows
POST/{id}팔로우
DELETE/{id}언팔로우
🖼 Media/api/media
POST/upload파일 업로드 (HEIC 변환)
💬 Chat/api/chat + WS
POST/rooms채팅방 생성
GET/rooms/{id}/messages메시지 페이지네이션
STOMP/pub/chat.send실시간 메시지
SUB/sub/chat.{roomId}채널 구독
📸 SnapGuide
LAYERED · Java 17 · Spring Boot 3.4.5 · PostgreSQL+PostGIS · Redis
🔐 Auth/api/auth
POST/signup회원가입
POST/login로그인
POST/reissue토큰 갱신
POST/logout로그아웃
DELETE/delete계정 삭제
POST/google/tokenGoogle OAuth (모바일)
POST/oauth/tokenOAuth2 코드 교환 (웹)
📍 Guide/guide/api
POST/upload가이드 + 미디어 생성
GET/my내 가이드 목록
GET/{id}가이드 상세
GET/nearby반경 내 가이드 (PostGIS)
PATCH/{id}가이드 수정
DELETE/{id}가이드 삭제
POST/like/{id}좋아요 토글 (@Version)
🗺 Location/location
POST/api/upload위치 저장
GET/api/places/autocomplete장소 자동완성 (Google)
GET/api/places/details장소 상세 (Google)
🖼 Media/media
POST/upload파일 업로드
GET/list미디어 목록
GET/files/{filename}파일 서빙
GET/allphoto전체 사진 (페이지네이션)
GET/allphoto/count사진 총 개수
👤 Member/api/members
GET/전체 회원 조회
DELETE/me계정 삭제
🔔 Push/api/push
GET/vapid-public-keyVAPID 공개키
POST/subscribe푸시 구독
DELETE/unsubscribe구독 취소
POST/test테스트 알림
⏱ TimeManager
HEXAGONAL · Java 17 · Spring Boot 3.4.2 · H2 (dev) / PostgreSQL (prod)
🔐 Auth/api/v1/auth
POST/login이메일 로그인
POST/refresh토큰 갱신
POST/logout로그아웃
👤 Member/api/v1/members
POST/회원 등록
🏷 Tag/api/v1/tags
GET/태그 트리 조회
GET/{tagId}태그 상세
POST/태그 생성
PATCH/{tagId}태그 이동 (부모 변경)
⏱ STOPWATCH
POST/{tagId}/timer/start타이머 시작
POST/{tagId}/timer/stop타이머 정지 + 기록 저장
POST/{tagId}/timer/reset타이머 초기화
📊 Record/api/v1/records
GET/태그별 기록 조회
POST/기록 생성
PUT/{recordId}기록 시간 수정
DELETE/{recordId}기록 삭제
⚡ 생성/수정/삭제 시 상위 태그 누적 시간 자동 재계산
🔔 Push/api/push
POST/subscribe/{memberId}푸시 구독
DELETE/unsubscribe/{memberId}구독 취소
공통 설계 패턴
✓ JWT Stateless 인증 (모든 엔드포인트)
✓ PageResult<T> 제네릭 페이지네이션
✓ ZonedDateTime 타임존 지원
✓ 단일 타이머 정책 (서비스 레이어 강제)
Deployment & Version Control Flow
배포 파이프라인 & 운영 아키텍처 GitHub Actions · k3s · ghcr.io CI/CD · Kubernetes · Monitoring
CI / CD PIPELINE
Stage 0
🔀
코드 Push / PR
GitHub
push main 브랜치
PR 빌드·테스트만
dispatch 수동 실행
TRIGGER
Stage 1
🔨
Build & Test
Gradle · JUnit 5
JDK 21 환경 설정
./gradlew build
단위 테스트 38개 실행
실패 시 파이프라인 중단
ON PUSH
Stage 2
🐳
Docker Build & Push
ghcr.io 레지스트리
Backend 이미지 빌드
Frontend 이미지 빌드
:latest 태그 push
:sha-{commit} 태그 push
ghcr.io/yeonjae1220/ovlo
SSH DEPLOY
Stage 3
☸️
Deploy to k3s
온프레미스 Lenovo Server
SSH 접속 (시크릿 키)
imagePullSecrets 인증
kubectl set image
Rolling Update (무중단)
rollout status 300s 대기
LIVE
Production
🚀
서비스 운영
k3s Cluster · ovlo namespace
Readiness Probe 통과
Liveness Probe 모니터링
ingress-nginx 트래픽 라우팅
cert-manager SSL 자동 갱신
실패 시 자동 롤백 알림
롤백: SHA 태그로 즉시 이전 버전 복구 — kubectl set image deployment/ovlo-app ovlo=ghcr.io/yeonjae1220/ovlo:sha-{commit}
⚠️ 트러블슈팅: ghcr.io private registry → imagePullSecrets 설정, Node.js 24 런타임 업그레이드, 프론트엔드 rollout timeout 조정으로 해결
☸️ Kubernetes 리소스 구성 k3s (온프레미스)
NAMESPACE: ovlo
App
DEPLOYovlo-app
SVCClusterIP:8080
PVCmedia 10Gi
PROBEHealth /actuator
Frontend
DEPLOYovlo-frontend
SVCClusterIP:3000
INGingress-nginx
TLScert-manager
Data
STSPostgreSQL 16
PVCpg-data
DEPLOYRedis 7
PVCredis-data
네트워크 보안
✓ Traefik 비활성화 (불필요한 노출 제거)
✓ NodePort 최소화, ClusterIP 내부 통신
✓ ingress-nginx → 단일 진입점
✓ cert-manager → Let's Encrypt 자동 SSL
리소스 제한
CPU: 250m (req) / 1000m (limit)
Memory: 512Mi (req) / 1Gi (limit)
Readiness: 60s delay / 10s period
Liveness: 90s delay / 30s period
📊 Observability Stack MELT 통합 모니터링
📡
OTEL Collector
데이터 수집 · 라우팅
gRPC 4317 / HTTP 4318
🔥
Prometheus
메트릭 수집 · 9090
📋
Loki
로그 집계 · 쿼리
🔍
Tempo
분산 트레이싱
📈
Grafana
대시보드 · 시각화
Alert Rule · 3001포트
⚠️ Alert Rule 트러블슈팅: Grafana v10 alerting 엔진 변경(Reduce 단계 필수화)으로 DatasourceError 지속 발생 → Provisioning API로 수정 해결
💾 자동 백업 & 운영 crontab · NAS · 30일 보관
⏰ 매일 03:00
crontab 스케줄
🐘 pg_dump
PostgreSQL 전체 백업
+
📁 rsync PVC
미디어 파일 동기화
+
📊 Grafana API
대시보드 JSON 백업
🗄 NAS 전송
SSH · rsync
🗑 30일 후 자동 삭제
스토리지 효율 관리
🏷 버전 관리 & 브랜치 전략 Conventional Commits · SHA Tag
COMMIT CONVENTION
feat fix chore refactor ci docs test
예: feat(post): add optimistic lock for concurrent reactions
IMAGE 태깅 전략
코드 Push
main 브랜치
Docker Build
GitHub Actions
ghcr.io/yeonjae1220/ovlo:latest
ghcr.io/yeonjae1220/ovlo:sha-9918eb6
✅ 최신 배포
:latest 사용
🔄 롤백 시
:sha-{commit} 지정
교환학생 정보 수집 AI 데이터 파이프라인
2026.03 ~ 현재 (진행 중) · 개인 프로젝트 · Ovlo 연동
Python 3.12asyncio WhisperOllama / qwen3 PlaywrightSQLAlchemy
YouTube STT와 웹 크롤링 이중 채널로 전 세계 10,150개 대학의 교환학생 정보를 자동 수집·구조화하는 AI 파이프라인. Whisper로 자막 추출, Ollama LLM으로 GPA·언어·마감일을 JSON 자동 파싱하여 Ovlo DB 적재.
주요 성과
비동기 최적화: asyncio 20개 동시 HTTP 크롤러. 비동기 DNS 전환으로 17배 성능 저하 해결 12개/분 → 35개/분
LLM 최적화: qwen3:14b → qwen3:8b 교체, VRAM 절감 + 6배 향상 (4분 → 39초). 2,835개 영상 분석 완료
안정성: Playwright wait_for()로 무한 행 해결. JSONL 체크포인트 + Atomic 저장으로 크래시 후 이어서 처리
Watchdog: 자동 재시작. byte offset 추적으로 OOM 허위 감지 114회 문제 해결
실시간 대시보드: Rich ANSI 터미널 대시보드. Phase 진행률·ETA·Ollama 상태 실시간 시각화
System Architecture · AI 기반 교환학생 정보 수집 파이프라인
전체 데이터 흐름 아키텍처 Python 3.12 · GPU 가속 · 멀티 파이프라인 Ovlo 서비스 연동
10,150대학 기본 데이터
2,835처리된 YouTube 영상
2,247생성된 정보 레코드
39초/영상LLM 처리 속도
35개/분크롤링 처리량
20+구조화 JSON 필드
4수집 데이터 소스
① Data Sources
외부 데이터 수집 채널 — 4가지 소스에서 멀티채널 수집
▶️
YouTube
교환학생 브이로그
10,150개 대학 검색
대학당 7개 영상 목표
영어 + 현지어 다국어 쿼리
Rate Limit: 3~5초 간격
🏫
대학 공식 웹사이트
공식 교환학생 정보
5개 언어 URL 패턴 (55종)
/exchange · /international
서브도메인 + DuckDuckGo 폴백
PDF · DOCX · HWP 파싱
💬
Naver Cafe
커뮤니티 정보
교환학생 커뮤니티 게시글
실제 경험 기반 정보
Playwright JS 렌더링
🗺️
TourAPI
관광명소 데이터
포토스팟 지리 데이터
PostGIS 좌표 저장
YouTube 영상과 연계
수집 요청
② Collection Layer
파이프라인별 수집 엔진 — 각 소스에 최적화된 수집 방식 적용
🎬
Pipeline 1 — YouTube
ovlo/ · yt-dlp 기반
yt-dlp 영상·음성·메타데이터
자막 우선 사용 → 없으면 STT
배치 단위: 200개 대학씩
JSONL 체크포인트 재개
✓ 2,835개 영상 처리완료
🕷️
Pipeline 2 — 웹 크롤러
web_crawler/ · BS4 + Playwright
정적: BeautifulSoup4 HTML 파싱
동적: Playwright JS 렌더링
20~30개 비동기 동시 요청
PDF·DOCX·HWP 문서 파싱
✓ 12/분 → 35/분 (비동기 DNS)
📸
Pipeline 3 — SnapGuide
snapguide/ · TourAPI + YouTube
YouTube API 포토스팟 영상
TourAPI 관광명소 연계
PostGIS 지리 좌표 매핑
photo_spots → photo_videos
원시 데이터
③ AI Processing Engine
GPU 가속 STT + 2단계 LLM 분석 — 비구조 텍스트 → 구조화 JSON
🎙️
Whisper STT
faster-whisper large-v3-turbo
GPU 가속: RTX 3080 · CUDA 12
BatchedInferencePipeline (병렬)
VRAM ~3GB 사용
타임아웃: 5분/영상
체크포인트: tmp/stt_checkpoint.json
large-v3 대비 2배 속도 · VRAM 50%↓
🤖
LLM 2단계 분석 엔진 — Ollama (qwen3:8b) + Claude API 폴백
비구조 텍스트 → 20+ 구조화 JSON 필드 자동 추출
Stage 1 · 핵심 정보 지원 일정 & 절차
비자 요건
기숙사 & 숙소 옵션
생활비 (월 예상)
수업 & 학점 인정
Stage 2 · 감성/주관 전반적 만족도 (1-5)
긍정/부정 감정
핵심 팁 & 주의사항
인상적인 인용구
추천 여부
최적화 이력 qwen3:14b → qwen3:8b
4분/영상 → 39초/영상
6배 처리속도 향상
VRAM: ~5GB/워커
폴백: Claude API
📄
File Parser
문서 형식별 파싱
PDF → pdfplumber
DOCX → python-docx
HWP → olefile
텍스트 전처리 후 LLM 전달
실시간 리소스 감시
④ Scheduler — Resource Orchestrator
30초 폴링 · GPU/VRAM/네트워크 자동 조율 · 히스테리시스 알고리즘
RESOURCE MONITOR
VRAM (pynvml)  •  GPU%  •  Network Mbps
10초 롤링 평균 · psutil
DECISION LOGIC
VRAM > 9GB → LLM 워커 2개↓
GPU > 92% → 신규 태스크 정지
DL > 3Mbps → yt-dlp 정지
연속 3회 초과 후 액션 · 쿨다운 90초
PROCESS MANAGER
SIGSTOP / SIGCONT · subprocess
스톨 감지: 10분 무활동 → 강제 종료
체크포인트 추적 · Watchdog 재시작
RICH TUI DASHBOARD
프로세스 상태 · 리소스 게이지 · 로그 테일(20줄)
배치 Phase 진행률 · ETA · Ollama 상태
ANSI 터미널 실시간 시각화
SQLAlchemy upsert
⑤ Storage Layer
PostgreSQL 16 + PostGIS + pgvector + Redis — 구조화 + 벡터 + 지리 통합 저장소
🐘
PostgreSQL 16
Docker · port 5432 · 확장: PostGIS · pgvector · pg_trgm
universities10,150개 레코드
name · country · city
qs_rank · website
video_data영상 메타데이터
transcript · summary
JSONB + embedding
(pgvector 유사도)
exchange_info구조화 교환 정보
visa · dormitory
living_cost
JSONB 20+ 필드
photo_spotsPostGIS geography
지리 공간 쿼리
photo_videos 연결
tips JSONB
Redis 7
Docker · port 6379
세션 캐싱
태스크 큐
Celery 브로커
임시 상태 저장
Data Export Pipeline
⑥ Export Layer
Ovlo 서비스 DB 연동 — 단계별 임포트 스크립트 + Flyway 마이그레이션
1️⃣
step1_fetch_global_universities.py
글로벌 대학 기본 데이터 추출
2️⃣
step2_fix_university_mapping.py
ID 재매핑 처리
Pipeline DB ↔ Ovlo DB ID 정합성
SQLAlchemy fetchone-after-commit 버그 → commit 순서 재조정
3️⃣
step3_import_to_ovlo.py
Ovlo 서비스 DB 임포트
kubectl port-forward 경유
WHERE NOT EXISTS 중복 방지
🗄️
V10__create_global_university_tables.sql
Flyway 마이그레이션
exchange_university 테이블
video_review 테이블
스키마 버전 관리
서비스 공급
⑦ Ovlo Service (k3s Cluster)
파이프라인 수집 데이터의 최종 소비자 — 교환학생 커뮤니티 플랫폼
⚙️
Spring Boot 4 Backend
Java 21 · 헥사고날 아키텍처 · Virtual Threads
ExchangeUniversityApiController
교환대학 검색 + 방향 분류 (파견/유치)
영상 리뷰 집계 쿼리 (N+1 방지)
🐘
PostgreSQL (Service DB)
Flyway V10 마이그레이션 적용
exchange_university 테이블
video_review 테이블
⚛️
React 19 Frontend
교환대학 탐색 UI
키워드 + 국가 필터 검색
영상 리뷰 상세 페이지
TanStack Query 캐싱
Pipeline Detail Flow & DB Schema · AI 기반 교환학생 정보 수집 파이프라인
파이프라인 상세 흐름 & 데이터베이스 스키마 Pipeline 1 (YouTube) Pipeline 2 (Web Crawler) Scheduler
Pipeline 1 YouTube 수집
ovlo/ · yt-dlp + Whisper + Ollama · 배치 200개씩
Input
🎓 universities_all.json
10,150개 대학 목록
배치 단위: 200개씩 처리
PHASE 1A
Phase 1A · 다운로드
▶️ YouTube 검색 & yt-dlp
검색: "{univ} exchange student vlog"
영어 + 현지어 다국어 지원
대학당 7개 영상 목표
Rate Limit: sleep 3s / 5s
메타데이터 · 자막 · 음성 파일
자막 여부 분기
자막 있음
자막 파일 직접 사용
STT 생략 → 빠른 처리
자막 없음
음성 파일 → Whisper
STT 변환 필요
PHASE 1B (자막 없는 경우)
Phase 1B · STT
🎙️ Whisper STT
faster-whisper large-v3-turbo
BatchedInferencePipeline
GPU: RTX 3080 · VRAM ~3GB
타임아웃: 5분/영상
체크포인트: tmp/stt_checkpoint.json
large-v3 대비 2배↑ · VRAM 50%↓
PHASE 2
Phase 2 · LLM 분석
🤖 Ollama qwen3:8b — 2단계
Stage 1: 지원/비자/숙소/비용/학업
Stage 2: 만족도/팁/감정분석/인용구
출력: 구조화 JSON (20+ 필드)
폴백: Ollama 실패 → Claude API
retry + exponential backoff
qwen3:14b 4분 → qwen3:8b 39초 (6배↑)
SQLAlchemy upsert
Output · 저장
🐘 PostgreSQL — upsert
video_data: 영상 메타·트랜스크립트
exchange_info: 구조화 교환 정보
URL 기반 중복 방지 (UNIQUE)
✓ 2,835개 영상 · 2,247개 레코드
Pipeline 2 웹 크롤러
web_crawler/ · BS4 + Playwright · 비동기 aiohttp
Input
📋 대학 목록 CSV
10,150개 대학명 + 웹사이트
국가 코드 · QS Rank 포함
STEP 1
Step 1 · URL 발견
🔍 1_discover_urls.py
1순위 URL 패턴: /exchange, /international
2순위 서브도메인: exchange.*.edu
3순위 홈페이지 링크 스캔
4순위 /international 내 링크
5순위 DuckDuckGo 검색 폴백
5개 언어 패턴 (55종)
체크포인트: cache/url_discovery.jsonl
STEP 2
Step 2 · 크롤링
🕷️ 2_crawl_pages.py
정적: BeautifulSoup4 HTML 파싱
동적: Playwright JS 렌더링
동시성: 20~30개 비동기 요청
타임아웃: 20초/페이지
필터: 30단어 미만 제외
2b: PDF 링크 수집
2c: pdfplumber 내용 추출
체크포인트: cache/crawled.jsonl
STEP 3
Step 3 · LLM 추출
🤖 3_llm_extract.py
병렬 처리: 4개 워커
Whisper 활성 시 → 2개로 자동 축소
배치 단위: 대학별 묶음
다국어 텍스트 LLM 위임 처리
체크포인트: cache/extracted.jsonl
STEP 4
Step 4 · 병합 & 내보내기
🔀 4_merge_and_export.py
Pipeline 1 YouTube 데이터와 병합
대학별 중복 제거 (URL 기반)
출력: exports/exchange_info.csv
Scheduler 리소스 오케스트레이터
scheduler_engine.py · 30초 폴링 · GPU/VRAM/네트워크 자동 조율
Loop
🔄 30초 폴링 루프
scheduler_engine.py 실행
3개 파이프라인 동시 관리
Monitor
📊 Resource Monitor
VRAM 사용량 (pynvml)
GPU 사용률 %
네트워크 DL/UL Mbps (10초 롤링)
CPU · 메모리 (psutil)
Decision
🧮 Decision Logic
VRAM > 9.0GB → LLM 워커 2개↓
GPU > 92% → 신규 태스크 정지
DL > 3.0Mbps → yt-dlp 정지
히스테리시스: 연속 3회 초과만 액션
쿨다운: 액션 후 90초 대기
플래핑 방지 알고리즘
Action
⚙️ Process Manager
subprocess spawn / 종료
SIGSTOP / SIGCONT 일시정지·재개
스톨 감지: 10분 무활동 → 강제 종료
Watchdog 자동 재시작
byte offset 추적 (허위 OOM 방지)
Watchdog 허위감지 114회 → 0회
Dashboard
🖥️ Rich TUI Dashboard
ANSI 터미널 실시간 시각화
프로세스 상태 (실행/정지/완료)
VRAM / GPU / 네트워크 게이지
배치 Phase 진행률 + ETA
로그 테일 (최근 20줄)
Ollama 서버 상태 감지
핵심 성능 최적화
LLM 모델 교체 qwen3:14b · 4분/영상 qwen3:8b · 39초/영상 (6배↑)
비동기 DNS 전환 setdefaulttimeout() 전역 → 12개/분 loop.getaddrinfo() → 35개/분 (17배 회복)
Whisper 모델 large-v3 기준 large-v3-turbo: 2배↑ · VRAM 50%↓
동적 워커 스케일링 고정 4개 → OOM 빈발 VRAM 상황별 2~4개 자동 조절
🐘 데이터베이스 스키마 PostgreSQL 16 + PostGIS + pgvector + pg_trgm
🏫 universities
PKid
UNIQname_en
name · country · city
latitude · longitude
qs_rank · website
10,150개 레코드
1 : N
🎬 video_data
PKid
FKuniversity_id
UNIQurl
source · title · channel
TEXTtranscript · summary
JSONBlocations · exchange_info
JSONBphoto_tips · tags
VECembedding (pgvector)
유사도 벡터 검색 지원
EMBED
📋 exchange_info
PKid
FKuniversity_id
UNIQsource_url + university_id
visa_info · dormitory
courses · living_cost
INTdifficulty (1~5)
JSONBapplication · visa
JSONBhousing · costs
JSONBacademics · life
JSONBevaluation · sentiment
20+ 구조화 필드
🗺️ photo_spots
PKid
name · country · city
GEOlocation (PostGIS)
JSONBbest_time · tags
1 : N
🎥 photo_videos
PKid
FKphoto_spot_id
url · transcript
JSONBtips
핵심 트러블슈팅
Issue 01
비동기 DNS 성능 저하
❌ setdefaulttimeout() 전역 적용 → asyncio 17배 저하 · 12개/분
✅ loop.getaddrinfo() 비동기 전환 → 35개/분 회복
Issue 02
SQLAlchemy FK 위반
❌ fetchone()-after-commit() 버그 → FK 위반 오류
✅ commit 순서 재조정 → 정합성 보장
Issue 03
Watchdog 허위 OOM
❌ 전체 로그 재스캔 → OOM 허위 감지 114회
✅ byte offset 추적 → 신규 로그만 스캔
Issue 04
Playwright 무한 행
❌ browser.close() 무한 hang
✅ asyncio.wait_for(timeout=10) 래핑
SnapGuide
2025.08 ~ 현재 (진행 중) · 개인 프로젝트
Spring BootSpring Security DockerGitHub Actions PostGISRedis
Docker, GitHub Actions, Jira를 활용하여 개발~배포 전 과정을 자동화한 프로젝트. Spring Security 기반 멀티 플랫폼 인증과 위치 기반 성능 최적화 구현.
주요 기여
인증: Spring Security + JWT + Redis. OAuth2.0 Google 로그인, 웹/앱 멀티 플랫폼 아키텍처
성능: PostGIS 공간 인덱스 + 캐싱 1393ms → 6ms (232배). 비동기 업로드 1491ms → 450ms (3.3배)
DevOps: Docker Compose 환경 구축. GitHub Actions + Jira 자동 연동
코드 품질: JUnit 단위 테스트 + 명확한 커밋 메시지 관리
TimeManager
2024.11 ~ 2025.03 · 개인 프로젝트
Spring BootQueryDSL Vue 3PostgreSQL
계층적 태그 시스템으로 측정 시간을 분류하고 데이터를 시각화하여 생산성 향상을 목표로 하는 웹 기반 시간 관리 애플리케이션.
주요 기여
타입 안전한 DB: Spring Data JPA + QueryDSL. 커스텀 리포지토리 패턴으로 가독성·확장성 확보
계층형 아키텍처: DTO 패턴으로 API/도메인 분리. LAZY 로딩으로 N+1 방지
Vue 3 UI: Composition API 반응형 타이머. Axios RESTful 실시간 동기화
TodoTimer
2022.09 ~ 2022.12 · 팀 프로젝트
AndroidMVVMRoomLiveData
항목별 시간 측정 데이터를 시각화하여 성취감과 동기를 제공하는 안드로이드 할 일 관리 애플리케이션.
주요 기여
Room Persistence: 데이터 무결성·확장성 고려한 로컬 DB 설계
MVVM: Repository 패턴으로 데이터 추상화. ViewModel + LiveData로 UI/비즈니스 로직 분리, 생명주기 안전성 확보

04

학력

경북대학교
글로벌소프트웨어융합전공
2022.03 ~ 2025.08
부경대학교
IT융합응용공학과
2018.03 ~ 2022.02