전체 글 187

반복되는 일정 서비스 API콜에 대한 캐시 적용 및 전략

서문이전 DTO 프로젝션 적용 후, 응답 시간이 두 자릿수(ms) 수준으로 개선되어 사용자 경험 측면에서는 불편함이 거의 사라졌습니다.그러나 일정 서비스의 과거 게임 데이터는 불변성이라는 특성을 가지고 있기에, 캐시를 활용하여 더욱 최적화를 할 수 있다고 판단하였습니다.본문서비스 특성 고려하여 캐싱 전략 수립 LCK 일정 서비스 업데이트 주기가 6시간 간격으로 스케줄링을 통해 저장됩니다. 하지만 오늘 경기가 아직 진행중일 경우 절반만 업데이트되는 경우가 있을 수 있습니다. 이럴 경우를 대비해 총 5가지의 캐시로 분류하였습니다. 오늘 경기 일정오늘 경기 상세정보 과거 경기 일정과거 경기 상세정보 기록 페이지 오늘 경기 일정, 상세정보는 과거 데이터들과 다르게 스케줄링이 성공하면 @CacheEvict를 통..

나르지지 2025.08.15

DTO 프로젝션을 활용한 일정 서비스 성능 개선

문제 상황일정 서비스 로직은 단순한 조회 기능인데, 사용자가 체감할 정도의 응답 지연(약 750ms)이 발생하고 있었습니다. 접근스프링단 코드는 크게 이상이 없어 DEBUG 레벨 로그로 설정해보았습니다.API 조회 콜 1개당 수많은 쿼리문이 발생하였습니다. 바로 N+1문제였습니다. 원인ONE TO ONE 양방향 매핑 N+1 문제연관관계 주인 - game_player_stat반대 - game_participant GameParticipant 조인 시 GamePlayerStat도 EAGER 방식으로 가져오게 되어 문제 발생 자식 쪽에서는 부모 존재여부를 모르기 때문에 체크하게 되어 LAZY방식 작동안하게 됨해결책@OneToOne(optional = false) (DTO 프로젝션과 비교분석함)JOIN FE..

나르지지 2025.08.15

8만 건 데이터 DB 마이그레이션 자동화 구축

들어가며나르지지 서비스는 Riot에서 제공하는 대회 데이터 기반으로 분석 서비스를 제공하는 것을 목표로 합니다. 위와 같이 서버 단에서 데이터 수집 및 정제 후 DB에 저장하여 가공한 서비스를 제공하는 것이 목표입니다. 이를 위해 주기적으로 업데이트되는 Google Drive 파일을 우리 서비스에서도 똑같이 업데이트해야됩니다. 진행 사항 스케줄링 Google Drive 파일이 6시간 간격으로 업데이트 됩니다.@Scheduled(cron = "0 30 4,10,16,22 * * ?", zone = "Asia/Seoul") 이에 맞춰 저희 서비스에서도 6시간 간격으로 스케줄링을 설정하였습니다. Data Ingestion DataIngestionFacade역할 : 데이터 수집 프로세스 전체를 총괄합니다...

나르지지 2025.08.06

OOM 원인 API, DB 최적화로 해결하기

들어가며- 롤 e-스포츠 데이터를 다루는 개인 프로젝트 ‘NAR’에서 “챔피언 조합 통계(Combination)” API를 만들었습니다.- 첫 구현은 메모리 중심 설계로 하였습니다. DB에서 GameParticipant 전부를 읽어 와 자바 컬렉션으로 그룹핑, 집계, 정렬, 페이징까지 처리하는 방식입니다. 문제상황서비스 운영 중, java.lang.OutOfMemoryError: Java heap space 에러가 터짐. 로그를 확인해보니 챔피언 조합 통계 API가 반복적으로 호출됨. 운영 환경 인스턴스: AWS EC2 t3.micro (vCPU: 2, Memory: 1GB)JVM 옵션 : -Xmx512m 성능 테스트 (기존 코드)정확한 진단을 위해 VisualVM 모니터링 툴을 이용하여로컬에서 운영..

나르지지 2025.07.31

[Riot API] 비동기 전적조회 리팩토링으로 응답속도 개선하기 (2차)

1차 리팩토링: 구조 개선 + 비동기 전환(1차 리팩토링 글 : https://changha-dev.tistory.com/188 )처음 진행한 리팩토링에서는 다음과 같은 개선을 통해 구조적 안정성과 기본적인 성능 향상을 도모했습니다:외부 API URL 하드코딩 문제 → HttpInterface와 RestClient 기반으로 추상화하여 가독성과 유지보수성 향상전적 조회 10건을 순차적으로 호출하던 방식 → CompletableFuture와 ThreadPool을 활용한 비동기 처리 방식으로 전환이 과정을 통해 기존 평균 2~3초 걸리던 요청을 1초 미만으로 단축하는 데 성공했습니다. 그러나... 성능은 아직 충분하지 않았다비동기 구조로 전환한 이후, 내부 처리 시간 자체는 약 500ms 수준으로 빨라졌지만실..

티모지지 2025.07.08

TIMO.GG를 만들면서

작년 12월부터 지금까지, 내 머릿속 절반은 TIMO.GG로 가득 차 있었다고 해도 과언이 아닌 것 같다..작년 디자이너분이 만들어주신 귀엽고 정감 가는 로고와 캐릭터 덕분에, 이 프로젝트에 더 큰 애정을 갖게 된 것 같다. 대학 생활 중 정말 다양한 프로젝트를 해봤지만, 실제 서비스로 운영까지 간 적은 없었다. (대부분 비즈니스 모델의 한계 때문이었다)그래서 이번에는 ‘우리가 좋아하고 직접 써볼 수 있는 서비스’를 만들고, 끝까지 운영까지 해보자는 목표를 세웠다. 이 프로젝트를 진행하며 가장 집중한 부분은 무엇이었을까?사용자 중심적 사고 회원가입 플로우 단순화기본 닉네임 자동생성티모대위-a12b42(랜덤UUID 활용)오직 OAuth 로그인 통한 비밀번호 미사용→ 유저가 빠르게 서비스를 경험하는 것이..

티모지지 2025.07.07

[책 후기] 컴퓨터 밑바닥의 비밀

이 책을 읽게 된 이유취준 단톡방을 통해 처음 접하게 되었다. 요즘 취준하면서 부족한 CS를 채우려고 노력하는데 이 책의 목차를 보고 꽤 중요한 개념들이 있어서 바로 빌렸다.특히 CPU, 메모리 관리, 스레드, 프로세스, 동기/비동기, 블로킹/논블로킹 이러한 개념들은 알아도 계속 학습을 안하면 휘발되어서 다시 한번 숙지하자는 목표도 있었다. 어떠한 내용들이 있었나운영체제에서 하드웨어까지 전반적으로 필요한 개념들은 모두 주제로 등장한 것 같다. 이 책의 목표는 책 제목처럼 컴퓨터 밑바닥의 비밀을 아는 것, 즉 컴퓨터 내부의 동작원리를 파헤치는 것이다. 그런 관점에서 의문형으로 깊숙이 들어가는 구성이 도움이 되었다.[목차 일부] 대부분의 주제, 소제목이 의문형으로 되어있다.나에게 도움이 된 부분추상화이 책에..

책 후기 2025.07.07

[책 후기] 디자인패턴의 아름다움

바로 이전에 책을 읽고 디자인 패턴은 객체지향의 핵심인 역할, 책임, 협력 관점에서 반복되는 문제들을 해결하기 위해 개발자들이 자주 사용하는, 검증된 기법들을 정리한 것임을 알게 되었다. 그래서 디자인 패턴에 대해 좀 더 자세히 알아보기 위해서 읽게되었다. GoF의 디자인패턴 책이 유명하지만 학교 전자 도서관에서 지원을 안해서 선택하게 되었다.별점 (3.5/5) (후반부 디자인패턴쪽은 처음 접한 개념은 혼자 이해하기 쉽지 않았다.) 초반부는 객체지향 패러다임에 대해 소개해주는 부분이 있었고중반부는 코드 리팩토링 관점 후반부는 디자인패턴의 여러 개념및 적용 예시를 보여주었다. 특히 오늘 플라이웨이트 기법의 객체 재사용 측면에 대해 알게되었는데 Integer의 비교 기법에서 == 이 어떨 때 true이고 ..

책 후기 2025.07.04

@Transactional은 어떻게 동작하는걸까?

머리말프로젝트를 하다보면 @Transactional을 자주 쓰게 된다. 근데 이게 내부적으로 어떻게 동작하는지는 몰랐다. 그냥 마법처럼 스프링에서 관리해주는 어노테이션이라고 막연하게만 생각했다. 사용하기는 너무 쉽다. 트랜잭션이 필요한 곳에 메서드나 클래스에 @Transactional을 추가하면 된다. 근데.. 누군가 나에게 이것의 동작원리를 물으면 나는 뭐라고 답해야되나..(음... 지피티한테 물어볼게 잠깐만) 그래서 이번 기회에 한번 파헤쳐보려고한다. 본문일단 이것을 왜 사용해야될까? 먼저 트랜잭션의 사용이유를 알아보자. 트랜잭션이란 All or Nothing 원칙으로 작동한다.즉, 하나의 논리적 작업 단위에 포함된 모든 연산이 성공하면 커밋(Commit)하고, 하나라도 실패하면 모든 작업을 롤백(R..

개발 2025.07.01

[Riot API] RestClient + HttpInterface 도입 한 이유 (1차)

🚨상황 발단 사이드 프로젝트로 진행 중인 Tim.gg 서비스가 있다. 기능 중에 라이엇 외부 API를 활용하는 부분이 있다. 이 기능의 목적은 최근 10개의 매치 정보를 가져와서 승/패 횟수를 파악하는 것이다. 팀원의 기존코드로 작성했을 때 HttpClient로 작성되었었다. 작동하는데에는 문제가 없었지만 무언가 읽기 힘들다는 느낌이 들었었다.보면 알겠지만 URL을 일일이 메서드 안에 정의해줘야 한다. 매번 반복되는 HttpRequest, HttpResponse도 코드의 양을 늘이는 주범이다. 코드의 또 하나 문제인 부분이 여기서 List으로 매치정보를 가져오고 있다. 그 후 일일이 동기 방식으로 MatchSummaryDTO에 저장하고 있다.10개의 정보를 하나씩 해결하니까 웹사이트에서 은근히 처..

티모지지 2025.06.30