전체 글277 JPA, Redis, JMeter로 API 응답 속도 8초에서 200ms로 단축시킨 성능 개선기 이 글에서는 JMeter 부하 테스트를 통해 병목을 식별하고, JPA 쿼리 튜닝을 시작으로 Redis를 활용한 아키텍처 개선, 그리고 숨겨진 인프라 병목을 찾아내기까지, API 성능을 극한으로 끌어올린 과정을 단계별 코드와 함께 상세하게 공유하고자 합니다.테스트 시나리오성능 측정을 위해 다음과 같은 시나리오로 JMeter 부하 테스트를 진행했습니다.DBmember: 백개book: 천개reading_challenge: 만개reading_diary: 백만개reading_diary_like: 2백만개diary_comment: 백만개Jmeter스레드 수 (동시 사용자): 1000Ramp-up 기간: 10초 (10초 동안 1000명의 사용자가 접속)루프 횟수: 11단계: 첫 번째 병목 - 비효율적인 Group B.. 2025. 7. 12. Test Fixture 정착!! 프로젝트를 진행하면 여러 Test Fixture 방식들을 사용해봤지만 방식만의 장단점이 있어 어느 방식을 선택해야 할지 모호했습니다. 이번 기회에 자주 사용되는 Test Fixture 방식들을 살펴보고 앞으로 개인 프로젝트에서 사용할 Test fixture 방식을 정하겠습니다.1. 인라인 객체 생성가장 단순하고 원시적인 방법입니다. 모든 테스트 메서드 안에서 new 키워드나 빌더를 사용해 직접 객체를 생성합니다.방식: @Test 메서드 내부에 필요한 모든 객체를 즉석에서 생성합니다.장점:극강의 단순함: 별도의 클래스나 파일이 필요 없어 가장 빠릅니다.테스트 독립성: 테스트 메서드 하나만 보면 모든 준비 과정과 검증 과정을 이해할 수 있습니다.단점:높은 중복성: 비슷한 객체를 여러 테스트에서 생성하면 똑같.. 2025. 6. 13. JWT 인증 보안 취약점을 JWT쿠키로 해결과 CSRF 방어 JWT 인증 방식의 보안 강화를 위한 리팩토링프로젝트 초기, 사용자 인증은 JWT(Access Token)를 localStorage에 저장하는 방식으로 구현되었습니다. 이 방식은 구현이 간단하다는 장점이 있지만, 치명적인 보안 취약점을 내포하고 있음을 인지하고 보안 강화를 위한 리팩토링을 진행했습니다.문제 상황초기 인증 아키텍처는 클라이언트가 로그인 시 발급받은 Access Token을 브라우저의 localStorage에 저장하고, 이후 API 요청 시마다 이 토큰을 Authorization 헤더에 담아 보내는 방식이었습니다.핵심 문제: localStorage는 JavaScript를 통해 쉽게 접근할 수 있어 XSS(Cross-Site Scripting) 공격에 매우 취약합니다. 만약 웹사이트에 단 하나.. 2025. 6. 7. 인증정보 저장방식과 전달 정보를 기준으로 세션, 쿠키, JWT 이해 HTTP 프로토콜의 Connectionless와 Stateless 특성 때문에, 사용자가 로그인해도 서버는 상태를 기억하지 않습니다. 즉, 로그인 이후 매 요청마다 다시 인증 정보를 보내지 않으면 인증된 상태를 유지할 수 없습니다.하지만 실제 웹 애플리케이션에서는 로그인을 한 번 하면 이후 여러 페이지에서 반복 로그인을 하지 않아도 접속이 유지됩니다. 그 이유는 인증 정보를 클라이언트 혹은 서버에 저장하고 매 요청마다 인증 정보를 포함시키기 때문입니다. 그것이 어떻게 가능한지 살펴보겠습니다.인증방식을 세션과 쿠키와 JWT로 나누어서 이해하기에는 다소 이해가 힘들어 인증정보 저장방식과 전달 정보로 나누어 글을 작성하였습니다.먼저 인증정보 저장공간에는 클라이언트의 sessionStorage, localSto.. 2025. 5. 30. 도커 빌드는 외부에서 블루-그린 무중단 배포를 연습중이었습니다.블루에 해당하는 컨테이너를 올리고 그린에 해당하는 컨테이너를 올릴 때 ec2가 멈추었습니다.보시면 cpu사용량이 100퍼에 가까워져 뻑이 났습니다.위는 ti.micro 프리티어를 사용해서 RAM이 1GB로 매우 적기 때문에 발생했다 생각합니다.정확한 로그를 보기 위해 로그를 확인하겠습니다.ec2 재부팅 후 작업 → 모니터링 및 문제 해결 → 시스템로그 가져오기로그를 확인하려 했으나 재부팅 후 ec2 상태 검사가 통과된 것을 확인하여 문제가 해결되었습니다. 이러한 문제가 일어날 때마다 인스턴스를 재부팅하는 건 옳지 않다고 생각합니다.이를 해결하기 위해선 세 가지 방법이 있다 생각합니다.1. 자주 용량 비워주기. 1. `docker system prune`은 .. 2025. 5. 27. 레디스 철학, 자료구조, 클라이언트, 인코딩(’이것이 레디스다’ 책) 이 글은 레디스 명령어와 같은 단순한 정보가 아닌 레디스를 깊게 공부하기 위한 핵심들을 중점으로 작성하였습니다. 부족한 부분이 보인다면 부담 없이 피드백 주세요!1. NoSQL-레디스레디스는 NoSQL 데이터베이스의 한 종류입니다. 면접에서 "NoSQL의 특징이 무엇인가"와 같은 질문을 자주 접하지만, 사실 더 중요한 질문은 "언제 NoSQL을 써야 하는가"가 아니라, "우리 서비스의 특정 요구사항에 맞는 '어떤' NoSQL 데이터베이스를 써야 하는가" 입니다. NoSQL은 관계형 데이터베이스(RDBMS)가 아닌 다양한 데이터베이스를 **통칭**하며, 각기 다른 설계 목적과 강점을 가집니다.데이터 모델 (Data Model): 가장 중요합니다. 저장하려는 데이터의 형태와 접근 방식이 어떤 모델에 가장 잘.. 2025. 5. 16. 레디스 직렬화 4총사 1. 직렬화(Serialization)란?직렬화는 자바 객체를 저장하거나 네트워크로 전송할 수 있는 형태로 변환하는 과정입니다. 이 과정에서 객체는 일련의 바이트 스트림으로 변환됩니다.레디스 직렬화를 이야기 하기 앞선 직렬화에 대해서 정리하겠습니다. 저는 직렬화를 객체를 Json 으로 변환하는 것이라고 생각하였습니다. 그런데 StringRedisSerializer 는 다른 JsonRedisSerializer 들과 이름이 구별됩니다. 그렇다면 제가 직렬화의 정의를 잘못알고 있는 거 아닐까라는 생각에 직렬화의 정의를 다시 살펴봤습니다.직렬화(Serialization)는 객체(Object)의 상태를 저장하거나 전송하기 위해 바이트 스트림으로 변환하는 과정을 말합니다.즉, 직렬화 결과는 Json 뿐만 아니라 언.. 2025. 5. 16. Bitset 자료구조란 Bitset이란BitSet은 비트를 효율적으로 저장하고 조작할 수 있는 자료구조입니다.Bitset 사용 이유1. 메모리 효율boolean[]은 실제로는 한 요소당 1바이트 이상 사용되지만,BitSet은 64개의 비트를 long 1개에 담아 8바이트로 처리합니다.👉 즉, 대량의 true/false 값을 다룰 때 훨씬 가볍습니다.2. 성능비트 연산 (|, &, ^)을 통해 대량의 boolean 값을 한 번에 계산할 수 있어 빠릅니다.예: bitset1.and(bitset2) → 배열 전체를 순회하면서 동시에 AND 처리3. 개발자 실수 줄여줌Java는 정수 타입을 이용한 직접적인 비트 연산보다 BitSet을 사용할 때 더 읽기 쉽고 안전한 코드를 작성할 수 있게 해줍니다.컴파일러가 bitIndex 음수 체.. 2025. 4. 4. [백준 1949] 우수 마을 / 자바 / dp #문제레벨: G4알고리즘: dp풀이시간: 30분힌트 참조 유무: 무https://www.acmicpc.net/problem/1949#문제 풀이3개의 노드를 부모노드 - 자식노드 관점에서 보면 케이스는 위와 같이 4가지로 나누어집니다. 우린 dp를 자신의 노드가 우수마을인지 아닌지 나눠서 생각해봐야 합니다.dp[N][2] = 자식 노드 포함해서 현재 노드의 최고의 인원 수dp[i][0] = 자신이 우수노드가 아닐 때dp[i][1] = 자신이 우수노드일 때케이스2를 보면 자식 노드 2와 3은 서로가 우수마을이든지 아니든지 상관이 없습니다.즉, 옆 자식노드는 상관하지 않아도 된다는 것입니다.dp[i][1]은 자신이 우수노드인 경우이므로 케이스 1과 같이 자식들이 모두 우수노드가 아닌 경우의 수를 더해줘야합니다.. 2025. 2. 11. 이전 1 2 3 4 ··· 31 다음