본문 바로가기

백엔드17

캐시 사용전략 : 왜 Redis인가? 캐시 설계부터 동기화 github 저장소 taeung515/team-click-war동시성 문제와 캐싱 전략을 주제로 간단한 팀 프로젝트를 진행했습니다. 저는 인기 검색어를 캐싱하여 성능을 극대화하는 것을 목표로 삼았고, 캐시 방식 선택 과정에서 데이터 동기화 문제를 깊이 고민했습니다. 로컬 캐시 대신 Redis를 도입하게 된 배경과 그 이유까지 포함해, 프로젝트를 통해 얻은 인사이트들을 기록했습니다. 인기 검색어 조회를 이해하기 전에, 먼저 캐시 전략에 대해 설명드릴 필요가 있습니다. 저희는 강의 조건 검색 시 keyword를 바로 DB에 저장하는 Write-Around 방식을 선택했습니다. 그리고 인기 검색어를 조회할 때는 Look-Aside 전략을 적용했습니다. 이로써 매 요청마다 DB에 접근하지 않고 캐시에서 먼저 데.. 2025. 8. 24.
코드 refactor 과제: 리팩토링하며 생각했던 것들과 배운 것을 기록 코드 커밋 변경파일 단계별 기록: Commits · taeung515/spring-plus GitHub - taeung515/spring-plus: spring-plusspring-plus. Contribute to taeung515/spring-plus development by creating an account on GitHub.github.com이번 글에선 코드 리팩토링을 진행하며 생각했던 것들과 배운 것들을 기록하며 공부하고자 합니다. 목차는 다음과 같습니다.목차ToMany 페이징 서치과제에서의 경험근본적 문제로 돌아가기유저생성 속도 개선100만명의 유저 더미 생성조회속도 개선QueryDSL을 사용하는 이유와 @QueryProjection feat.타입안정성ToMany 페이징 서치더보기요구사항 .. 2025. 7. 4.
데이터베이스 연결 최적화: OSIV, CQRS패턴까지 목차데이터베이스는 커넥션을 매번 획득해결책: 커넥션 풀커넥션 생명주기 관리: OSIVOSIV ONOSIV OFFCQRS왜 분리하는 것이 좋을까요?데이터베이스는 커넥션을 매번 획득커넥션 획득 과정:더보기애플리케이션은 DB 드라이버를 통해 커넥션을 요청합니다DB 드라이버는 데이터베이스와 TCP/IP 소켓 통신을 시작합니다 (3-way handshake)연결된 소켓을 통해 ID, 비밀번호 등 인증 정보를 전달합니다데이터베이스는 인증을 확인하고, 내부에 세션을 생성합니다생성이 완료되었다는 응답을 보냅니다DB 드라이버는 이 정보를 바탕으로 커넥션 객체를 생성하여 반환합니다이 모든 과정은 애플리케이션 서버와 데이터베이스 서버 양쪽 모두에 리소스를 소모하게 하고, 특히 시간이 많이 걸린다는 점에서 문제가 됩니다. 사.. 2025. 7. 2.
Lock Concurrency Issue - 동시성 이슈여러 쓰레드(Thread)나 프로세스(Process)가 동시에 공유자원에 접근할 때 발생하는 모든 문제 Race Condition - 경합 조건동시성 이슈중 한개한개의 자원에 여러개의 쓰레드가 동시에 접근했을 때 실행 타이밍에 따라 결과가 달라지는 문제 Lock공유 자원에 대한 동시 접근을 제어하는 매커니즘데이터 무결성을 보장해준다 Shared Lock(공유락) vs Exclusive Lock(배타락)Shared Lock, S-Lock동일한 데이터를 여러 트랜잭션이 동시에 읽는것은 허용, 쓰기 불가Serializable과 같은 높은 격리수준에서는 일반 Select문에서 S-Lock 획득// 명시적 S-Lock 획득SELECT * FROM account WH.. 2025. 6. 27.
데이터베이스 동시성과 격리 수준 목차DB 동시성과 격리 수준TransactionACIDDB 격리 수준동시성 문제(격리를 제대로 하지 않았을 때)격리수준(Isolation Level) 종류DB 동시성과 격리 수준Transaction더 이상 나눌 수 없는 작업의 최소 단위(DB) Query들의 집합 / (Server) 메소드들의 집합ACIDAtomicity - 원자성트랜잭션 내의 작업들은 모두 성공하거나 모두 실패해야한다Consistency - 일관성트랜잭션 Commit 이후 DB는 항상 일관된 상태여야한다.DB에 정의된 제약조건을 준수해야합니다.Isolation - 격리성여러 트랜잭션이 동시에 진행될 때, 서로 간섭하지 않고 독립적으로 실행되어야 한다.Durability - 지속성트랜잭션이 Commit된 결과는 영구히 저장되어야 한다.D.. 2025. 6. 27.
아웃소싱 팀 프로젝트 회고: Docker로 프론트 연동 깃허브 레포지토리: https://github.com/taeung515/spring-practice프론트 연동 시연영상: https://www.youtube.com/watch?v=4DFnYRQ9CRQ목차프로젝트 개요:프로젝트 설계:엔티티 생성 시 빌더 패턴과 정적 팩토리 메서드스프링 시큐리티 컨텍스트 사용 전략@LastModifiedDate 적용 문제CORS 오류 해결추후 더 알아볼 것들마무리프로젝트 개요:외주 팀 프로젝트의 기한은 단 일주일! 프론트엔드 팀이 이미 개발을 완료했고, 현재 백엔드 연동을 기다리고 있는 상황입니다. API 명세서에 맞춰 정확하고 빠른 개발이 필요합니다!프로젝트 설계:팀원들과 함께 API 명세와 ERD를 작성하며 각자의 기능을 명확히 이해할 수 있었습니다. 공동응답객체와 코드.. 2025. 6. 23.
JWT, Spring security 목차Spring security의 동작 방식Spring security의 인증Spring security 인가메서드 단위 인가의 필요성메서드 단위 인가 적용 방법1. 메서드 보안 활성화2. 메서드에 어노테이션 추가하기3. 메서드 보안 어노테이션 설명4. 권한 표현식 예시Spring security의 동작 방식Spring security의 인증Spring security 인가[프레임워크/Spring] - 필터에서 예외처리 필터에서 예외처리필터내부에서 예외를 던졌을 때, @ControllerAdvice가 처리하지 못하고 500에러만 응답하는 이유에 대해서 알아보겠습니다.목차발생한 문제원인 분석처음 시도한 방법해결 방법발생한 문제Jwt 필터에ung9776.tistory.com필터에선 별도의 예외처리 전략이 필.. 2025. 6. 23.
Spring Boot에서 AOP와 Interceptor를 활용한 로깅 방법 목차Spring Boot에서 로깅의 중요성AOP(Aspect Oriented Programming) 관점지향프로그래밍Interceptor 인터셉터AOP와 Interceptor의 차이점로깅코드 예시⭐️⭐️!! 언제AOP, 언제Intrerceptor를 써야할까?Spring Boot에서 로깅의 중요성Spring Boot로 개발할 때 로깅은 디버깅, 트러블슈팅, 모니터링, 보안 등 모든 영역에서 필수적인 요소입니다.특히 사용자 요청(request)과 응답(response) 정보를 기록하면 이슈 분석이 훨씬 쉬워지고, 시스템 안정성을 높일 수 있습니다. AOP(Aspect Oriented Programming) 관점지향프로그래밍AOP는 공통관심사(로깅, 트랜잭션 등)를 핵심 비지니스 로직과 분리해서 관리하는 프로.. 2025. 6. 12.
테스트코드 알아보기 목차 테스트를 왜 해야 할까?테스트 코드는 왜 필요할까?테스트 코드 작성의 원칙1. FIRST 원칙2. 테스팅 7원칙테스트의 종류테스트 실습테스트를 위한 어노테이션단위 테스트 작성커버리지 향상 vs 의미있는 테스트 코드만 작성테스트를 왜 해야 할까?기능이 요구사항대로 잘 동작하고 있는지 확인해야하기 때문입니다.- 아무리 훌륭한 개발자여도 한번에 완벽한 코드를 구현한다는 것은 매우 어려운 일이고, 생각하지 못한 입력으로 인해 기능장애가 발생할 수 있기 때문에 다양한 케이스를 테스트를 통해 검증해야합니다. 테스트방법 Swagger, Postman등을 통해 여러 케이스들을 확인해보며 테스트를 진행QA 과정을 통해 UI, Front, Server까지 한번에 테스트테스트 코드를 만들어 테스트 진행테스트 코드는 왜.. 2025. 6. 12.
필터에서 예외처리 필터내부에서 예외를 던졌을 때, @ControllerAdvice가 처리하지 못하고 500에러만 응답하는 이유에 대해서 알아보겠습니다.목차발생한 문제원인 분석처음 시도한 방법해결 방법발생한 문제Jwt 필터에서 jwtUtil.validateToken 토큰의 유효성 검증 중 예외를 던졌을때 예상과 다르게 500 Internal Server Error가 발생하였습니다.원인 분석Spring에서 @ControllerAdvice는 DispatcherServlet 이후의 흐름에서 발생한 예외만 처리할 수 있습니다. 하지만 Filter, Interceptor등은 DispatcherServlet보다 앞단에서 실행되므로, 이 구간에서 발생한 예외는 @ControllerAdvice가 관여할 수 없습니다. 즉, 필터 내부에서 .. 2025. 6. 12.
JWT 인증 기반 뉴스피드 프로젝트: 회고 API 명세서 뉴스피드 프로젝트ERD 사용된 에러 코드documenter.getpostman.com 원격 코드 저장소 GitHub - taeung515/team-newsfeed-project: [ 내일배움캠프 Spring 7기 ] Chapter5. 스프링 팀 프로젝트 - 뉴스피드[ 내일배움캠프 Spring 7기 ] Chapter5. 스프링 팀 프로젝트 - 뉴스피드 프로젝트 - taeung515/team-newsfeed-projectgithub.com 뉴스피드 프로젝트 개발 및 리팩토링 과정 정리목차프로젝트1. 프로젝트 구조2. 구현 과정서비스 계층 설계RESTful API 설계Soft Delete 구현3. 사용자 삭제 시 연관관계 처리 방법1) DB 차원의 ON DELETE CASCADE2) 서비스 계층.. 2025. 6. 5.
JPA Schedule 프로젝트: 구현 중 발생한 트러블슈팅 목차AUTO_INCREMENT와 트랜잭션 롤백 시 ID 증가 문제DTO 분리 ?? Groups 사용??orphanRemoval사용?? Service계층에서의 로직 구현???JWT와 SessionAUTO_INCREMENT와 트랜잭션 롤백 시 ID 증가 문제 이번 프로젝트에서 User id는 AUTO_INCREMENT 방식으로 DB가 관리하도록 했습니다. 회원가입 시 email을 중복으로 입력해서 실패하면 에러가 납니다. 여기까지는 당연한 동작입니다. 문제는 그 다음입니다. 중복 이메일을 수정하고 다시 회원가입을 시도하면 id 값이 하나 건너뛰어 증가합니다. 예를 들어, 마지막 id가 1이었으면 실패 후 다음 성공 시 id가 3이 되는 식입니다.이해를 돕기 위한 사진더보기@Transactional을 적용하면.. 2025. 5. 23.
JPA Schedule 프로젝트: 유지보수성과 학습을 위한 단계별 구현과정 원격 저장소코드보기 (클릭) GitHub - taeung515/jpa-schedule: 사용자는 회원가입, 로그인 후 일정을 CRUD할 수 있습니다. 이 프로젝트사용자는 회원가입, 로그인 후 일정을 CRUD할 수 있습니다. 이 프로젝트는 JPA 기반으로 동작합니다. - taeung515/jpa-schedulegithub.com 요구사항에 맞게 어떤 생각을 하며 구현 하였는지 학습용으로 정리하며 커밋하였고, 그에 맞추어 다시 복습하며 정리하려고 합니다.이번 프로젝트의 목표는 JPA 사용에 익숙해지는 것과, 유지보수성!!!을 높이기 위해 서비스 계층에서 반복되는 코드를 최소화하면서도 전체 흐름을 명확히 이해할 수 있는 구조로 작성하는 것이었습니다. 우선 전체 단계를 먼저 설계한 뒤 코딩하는 것이 바람직하지.. 2025. 5. 23.
[자바] + OOP 다형성 OOP의 다형성의 핵심은 같은 참조 타입으로 다양한 객체를 다룰 수 있다 라는 점이다.예시코드// 부모 클래스class Animal { void sound() { System.out.println("Some generic animal sound"); }}// 자식 클래스들class Dog extends Animal { @Override void sound() { System.out.println("Woof! Woof!"); }}class Cat extends Animal { @Override void sound() { System.out.println("Meow!"); }}public class PolymorphismExam.. 2025. 4. 18.
[자바] +자바 메모리 구조 메서드 영역, 스택 영역, 힙 영역 메서드 영역(method area):공통 데이터를 관리한다. 이 영역은 프로그램의 모든 영역에서 공유한다.클래스의 실행코드, 필드, 메서드 와 생성자 코드등 모든 실행코드가 존재static 변수 보관공통 리터럴 상수 보관스택 영역(stack area):실행 시 하나의 접시가 쌓인다고 생각하자. 각 접시는 지역변수, 중간 연산결과, 메서드 호출 정보등을 포함한다.cf_) 각 쓰레드별로 하나의 실행 스택이 생성됨. 힙 영역(Heap Area):객체와 배열이 생성되는 영역. 가비지 컬렉션이 관여하는 영역. 참조되지 않는 객체는 바로 제거된다. 2025. 4. 15.
[자바] + 맵 자바의 Map 인터페이스는 키(key)와 값(value)의 쌍으로 데이터를 저장하는 구조를 제공한다. 각 키는 고유하며, 해당 키를 통해 연관된 값을 효율적으로 검색하거나 수정할 수 있다. 리스트와 배열과 다르게 맵은 순차적으로(sequential) 요솟값을 구하지 않고 키(key)를 이용해 값(value)을 얻는다. 맵에는 여러가지가 있지만 그중 가장 기본인 HashMap에 대해 알아보자. HashMap은 Java에서 가장 많이 사용하는 Map 구현체 중 하나다. 키(key)와 값(value)을 하나의 쌍으로 저장하며, 이 쌍을 "엔트리(entry)"라고 부른다. HashMap은 내부적으로 해시 테이블을 사용하여 데이터를 저장한다. 이 해시 테이블 덕분에 키를 이용한 검색, 삽입, 삭제 등의 작업이 .. 2025. 4. 8.
[MySQL] + rank, 서브쿼리 1. 고객별로 주문 건수와 총 주문 금액을 조회하는 SQL쿼리를 작성해주세요.select c.customername, count(1) OrderCount, sum(TotalAmount) totalSpentfrom customers c left join orders o on o.customerID=c.customerIDgroup by 11. 고객 이름과 국적은 Customer 테이블, totalamount는 Orders테이블 기대결과에 맞게 출력하려면 join 사용 필요2. 주문한적이 없는 고객도 결과에 포함되어야 하기때문에 left join 사용3. 고객 이름별 count와 Sum(totalAmount) 진행2. 나라별로 총 주문 금액이 가장 높은 고객의 이름과 그 고객의 총 주.. 2025. 3. 25.