MySQL DB 인덱싱을 통한 모듈 조회 성능 최적화
·
[프로젝트] Modulo
1. 문제 상황1.1 성능 측정회원별 모듈(프로젝트, 경력, 교육 등) 조회 시 603ms의 응답시간주요 원인: member_id 기반 조회 시 테이블 Full Scan 발생1.2 문제 분석SELECT * FROM project p WHERE p.member_id = ?위 쿼리 실행 시 인덱스 없이 전체 테이블 스캔다수의 연관 엔티티에서 동일 패턴 발생2. 해결 방안2.1 인덱스 설계@Entity@Table(indexes = @Index(name = "idx_project_member", columnList = "member_id"))public class Project extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColu..
MySQL 데이터베이스 마이그레이션하기
·
[프로젝트] Modulo
배경 Modulo 프로젝트는 사용자가 이력서를 간편하게 작성하고 조합할 수 있도록 하는 것이 주요 목적이었다. 프로젝트 진행 중 "README 작성이 없어서 아쉽다"는 피드백을 받았으나, README를 추가하는 것은 '간단한 이력서 작성'이라는 원래 취지에서 벗어난다고 판단했다. 대신 이력서 테마 기능을 추가하여 사용자 경험을 개선하기로 결정했다. 하지만 이 과정은 테이블을 수정해야 하는 일이였기에 바로 운영서버에서 테이블을 바꾸는것보다는, 개발 서버에서 먼저 테스트를 해본뒤에 운영서버에 적용하는 것이 나을 것이라고 생각하여 운영환경의 RDS 데이터를 개발 환경 Docker Container의 MySQL로 마이그레이션하여 테스트하기로 결정하였다.데이터 마이그레이션 과정1. RDS에서 데이터 덤프운영 환경..
Spring Boot Global Exception Handler 로깅 개선: X-Forwarded-For vs X-Real-IP
·
[프로젝트] Modulo
Spring Boot에서 예외 처리와 보안 설정 개선하기배경Spring Boot 애플리케이션에서 Global Exception Handler를 구현했으나, 운영 환경에서 유의미한 로그 수집에 어려움을 겪었다. 특히 NoResourceFoundException이 발생했을 때, 어떤 클라이언트가 어떤 경로로 요청했는지 파악하기 어려웠고, 보안 설정도 최적화가 필요했다.초기 상태와 문제점1. 로깅 시스템처음에는 다음과 같이 최소한의 정보만 로깅됐다:2025-01-13T03:35:42.369Z ERROR 1 --- [io-8080-exec-10] c.e.M.g.e.GlobalExceptionHandler : Class: NoResourceFoundException, Status: 500, Message: 내부 ..
Redis Cache 불일치 해결과 Cache Eviction 전략 개선
·
[프로젝트] Modulo
배경Modulo의 원활한 운영을 위해 Redis Cache를 도입했으나, 실제 운영 과정에서 캐시 동기화 문제가 발생했다. 이는 데이터베이스만 사용했을 때는 발생하지 않던 문제로, Redis Cache 도입 이후 Cache Eviction 이슈였다.Google Form 응답Q: Modulo 사용 중 불편했던 점이나 개선이 필요한 부분을 알려주세요.A: 이력서 모듈(프로젝트, 학력 정보 등)을 수정한 후 이력서 페이지로 돌아갔을 때 변경된 내용이 바로 보이지 않고 이력서에서 삭제 후 다시 추가를 해야 반영됩니다!요구사항 분석마주한 과제는 다음과 같았다:Cache 키 포맷 일관성 확보Cache Eviction 전략 개선연관 캐시 동기화 구현업데이트/삭제 시 일관된 캐시 처리Cache 키 포맷 통일모든 ..
Redis 캐시 도입을 통한 이력서 관리 시스템 성능 최적화: 응답 시간 87% 감소, 처리량 413% 향상 - Redis Template API vs Lua Script
·
[프로젝트] Modulo
1. 도입 배경이력서 관리 시스템 'Modulo'의 성능 테스트 중 여러 모듈(기본 정보, 경력, 학력, 프로젝트 등)의 데이터를 조합하는 과정에서 API 응답 시간 지연이 발생했다. 특히 SavedModule과 Resume 조회 시 여러 서비스의 데이터를 조합하는 과정에서 성능 저하가 두드러졌다. 캐시 도입 전 k6 성능 테스트 결과는 다음과 같다:# 캐시 적용 전 k6 테스트 결과✓ basic_info_get_all_duration....: avg=17.128329 min=13 med=15 max=232 p(90)=18 p(95)=21 ✓ resume_get_all_duration........: avg=43.515738 min=36 med=40 max=365 p(90)=47..
운영환경, 개발환경 분리하기
·
[프로젝트] Modulo
배경1월 7일 최종 테스트를 앞두고, 개발 환경과 운영 환경을 분리할 필요성이 생겼다. 기존의 개발 환경을 운영 환경으로 전환하고, 비용 효율적인 새로운 개발 환경을 구성하기로 했다.요구사항 분석팀에서 마주한 과제는 다음과 같았다:기존 개발 환경을 운영 환경으로 전환비용 효율적인 새로운 개발 환경 구성운영/개발 환경의 데이터 분리배포 자동화 구성현재 시스템은 EC2에서 애플리케이션이 실행되고 있었으며, 별도의 EC2에서 Nginx가 리버스 프록시 역할을 수행하고 있었다.운영 환경 구성기존 개발 환경을 운영 환경으로 전환하면서 다음과 같이 설정했다:spring: jpa: hibernate: ddl-auto: validate properties: hibernate: ..
MAU 측정하기(비관락, 낙관락, Write back)
·
[프로젝트] Modulo
배경1월 7일에 최종 테스트를 하고, 1월 8일에 정식으로 Modulo를 배포하기로 하였다. 1월 5일인 현재 모든 API 연동이 완료되었고, 실배포하기 전에 MAU를 측정을 구현하기로 했다.요구사항 분석팀에서 마주한 과제는 다음과 같았다:일별 활성 사용자(DAU)를 측정하고, 이를 월 단위로 집계하여 MAU 산출AOP를 활용한 사용자 활동 자동 측정실시간성 필요 없음. 익일에 확인 가능하면 됨데이터 정확성 보장시스템 확장성 확보현재 사용자 인증은 Spring Security를 사용하고 있었으며, SecurityContext의 ThreadLocal에서 사용자 ID를 가져오고 있었다:public class SecurityUtil { private static Long getCurrentMemberId..
[MONITOR] Prometheus+Grafana로 모니터링 환경 구축
·
[프로젝트] Modulo
Modulo의 현재 아키텍처k6로 부하 테스트를 진행하기 전에, 먼저 프로메테우스와 그라파나를 사용하여 모니터링을 구축하기로 하였다.왜?현재 Nginx, Spring Server, RDS 등 여러 서버로 분산된 환경에서 통합적인 모니터링의 필요성을 느꼈다. 향후 서비스 규모가 확장될 것을 고려하여(제발 확장하게 해줘), 중앙 집중식 모니터링 시스템 구축이 운영 효율성 측면에서 더 적합하다고 판단했다.S3는 왜 모니터링 안해?S3는 정적 파일 저장소로만 사용되고 있어 AWS CloudWatch의 기본 메트릭 모니터링으로 충분하다고 판단하여, 프로메테우스와 그라파나 모니터링 대상에서 제외했다.서버에 배포를 해야하는 이유?가장 큰 이유는 백엔드에 나 혼자 있다라는 것이다. 나 혼자 있어서 이걸 배포할 이유를 ..
[TEST] Domain 계층의 테스트를 작성하며
·
[프로젝트] Modulo
결과도메인 계층에서 테스트를 작성하며 느낀점도메인 계층에서 테스트를 작성하며 느낀점은 다음과 같다.이런 테스트가 굳이 필요한가? 라는 느낌을 생각보다 많이 느꼈다.예외 상황, 제약 사항등에 대해서 더 세세하게 설정하고, 이를 검토할 수 있었다1. 이런 테스트가 굳이 필요한가?작성할만한 테스트는 모두 작성했다고 생각했을때 테스트의 라인 커버리지는 87프로였다. 이에 의아해서 상세보기를 눌러서 확인해본 결과, toString에 대한 테스트 코드를 작성하지 않아서 라인 커버리지가 100이 안되는 거였다. 하지만 지금 상황에서 나는 toString을 사용하지 않을 생각이였고, 사용할 이유가 없었다. 이에 대한 해답은 다음 블로그에서 찾았다.https://toss.tech/article/test-strategy-..
[TEST] 테스트 커버리지 측정( 100% 달성 목표)
·
[프로젝트] Modulo
https://www.youtube.com/watch?v=jdlBu2vFv58왜?배포할때마다 불안해지는 내 자신을 발견하고, 이유를 찾게 되었다. 내가 찾은 이유는 다음과 같다.테스트 커버리지를 수치적으로 확인한적이 없다. 테스트 커버리지가 낮을거라는 생각이 머리 어딘가에 떠돌고 있었다.위 2가지를 어떻게 해결할 것인가?현재 백엔드는 지금까지 기획했던 기능은 모두 완료한 상태였다. 따라서 이제는 위 2가지 문제를 해결하기 위해 테스트 커버리지를 100%로 유지하고자한다.JaCoCo로 테스트 커버리지 측정하기build.gradle 수정plugins { id 'java' id 'org.springframework.boot' version '3.2.1' id 'io.spring.dependen..
kwon-record
'[프로젝트] Modulo' 카테고리의 글 목록