배포한 적도 없고, 에러 로그도 없는데 서비스는 N일마다 한 번씩 조용히 재시작되고 있었다. 처음엔 그냥 넘길 뻔했다. ECS 콘솔에 뜨는 재시작 정도는 발생할 수 있으니까. 그런데 이상한 점이 하나둘 늘어났다.배포 이력 없음에러 로그 없음OutOfMemoryError 없음HeapDumpOnOutOfMemoryError 옵션을 켜뒀는데도 OOM이었다면 남아있어야 할 힙 덤프가 없음몇 개의 서비스가 죽을 이유가 보이지 않는데 N일에 한 번씩 재시작되고 있었다. 테스크가 재시작 직후엔 50% 근처에서 시작해, N일에 걸쳐 서서히 99.8%까지 올라간다. 이런 메모리 사용 수치를 톱니 모양이라고 하더라. 메모리 누수처럼 보였지만 힙 덤프가 하나도 없다는 점이 이상했다. JVM이 정말 OutOfMemoryE..
API 요청을 제어하려면 Rate Limiting(속도 제한) 이 필요합니다.이 글에서는 API를 "1분 이내 30번 요청 가능하지만, 24시간 동안 최대 30번만 허용"하는 Bucket4j의 정책을 설정하는 방법을 다룹니다.*Bucket4j을 도입하는 방법을 설명하는 것은 아닙니다.Rate Limiting이란?Rate Limiting(속도 제한)은 특정 시간 동안 허용할 요청 수를 제한하는 기술입니다.예를 들어:"1분에 60개의 요청 가능" (API 남용 방지)"24시간 동안 100개의 요청 가능" (과도한 사용 제한)이러한 제한을 적용하면 서버 부하를 방지하고, 공정한 API 사용을 보장할 수 있습니다.Bucket4j로 정책 설정하기Bucket4j는 토큰 버킷(Token Bucket) 알고리즘을 기반..
새로 개발 중인 기능에 필요한 데이터 구조를 양방향 엔티티로 설계하게 되었습니다. 그런데 이 과정에서 양방향 참조로 인해 재귀 호출 문제가 발생하였고,이를 해결할 방법을 찾아보게 되었습니다. 예시 코드들은 업무와 무관하게 작성되었습니다. 문제 상황Category와 Product 엔티티는 양방향 연관관계를 가지고 있습니다. 예를 들어, Category는 Product의 리스트를 가지고 있고, Product는 다시 Category를 참조하는 구조입니다. 코드로 나타내면 다음과 같습니다.@Entity@Table(name = "category")public class Category { @Id private Long id; @OneToMany(mappedBy = "category", casca..
선착순 쿠폰 발급 시스템을 구현하는 방법에 대해 궁금하여 공부하며 기록 해보았습니다.1. 요구사항 정의이벤트를 진행하며, 선착순 100명에게만 할인 쿠폰을 지급하고자 합니다. 시스템은 아래의 조건을 만족해야 합니다.선착순 100명에게만 지급되어야 한다.많은 유저가 동시에 쿠폰을 요청할 때 트래픽을 버틸 수 있어야 한다.쿠폰 발급 시 데이터 정합성을 유지해야 한다.이러한 요구사항을 충족하기 위해 트랜잭션 관리, 동시성 처리, 비동기 시스템 구성 등 다양한 기술적 요소를 고려해야 합니다. 동시에 쿠폰 발급이 이루어질 때, DB에 과부하를 주지 않고 처리할 수 있는 방법도 필요합니다.2. 문제 해결 방안(1) Redis를 활용한 문제 해결Redis는 싱글 스레드 기반으로 동작하며, 내부적으로는 여러 가지 고유..
애플리케이션에서 여러 사용자가 동시에 같은 데이터를 수정하려 할 때, 동시성 문제(Race Condition)가 발생할 수 있습니다. 이런 문제를 해결하기 위한 방법으로 여러 접근 방식이 있습니다. 이번 글에서는 Spring에서 동시성 문제를 해결하기 위한 몇 가지 대표적인 방법을 살펴보겠습니다. 1. synchronized 키워드를 이용한 해결Java에서 가장 기본적인 동시성 처리 방법 중 하나는 synchronized 키워드를 사용하는 것입니다. 이를 통해 하나의 프로세스 내에서 동시에 여러 스레드가 동일한 리소스에 접근하지 못하도록 제어할 수 있습니다. 아래는 synchronized를 사용한 예시입니다.public synchronized void decreaseQuantity(Long id, Lon..
로그인 기능을 구현하다보니 Spring Security의 인증 과정에 대해 공부해야 했고, 그 중 아이디와 패스워드를 사용한 인증은 어떤 식으로 이뤄지는가에 대해 정리해 보았습니다.스프링 시큐리티가 제공하는 필터들WebAsyncManagerIntergrationFilterSecurityContextPersistenceFilterHeaderWriterFilterCsrfFilterLogoutFilterUsernamePasswordAuthenticationFilterDefaultLoginPageGeneratingFilterDefaultLogoutPageGeneratingFilterBasicAuthenticationFilterRequestCacheAwareFilterSecurityContextHolderAwar..