전체 글 30

Redis Streams의 PEL(Pending Entries List)과 장애 복구 시나리오

Redis StreamsRedis Streams는 append-only 로그처럼 동작하면서도, 일반적인 append-only 로그의 한계를 넘어서는 여러 연산을 지원하는 데이터 구조입니다. O(1) 시간의 랜덤 액세스와 Consumer Group 같은 복합적인 소비 전략이 이에 해당합니다. 각 엔트리는 고유 ID(- 형식)와 필드-값 쌍으로 구성됩니다. XADD로 엔트리를 추가하고, XREAD나 XREADGROUP으로 소비하며, XRANGE로 특정 ID 구간을 조회할 수 있습니다. 아래와 같이 발행, 소비 구조를 나타낼 수 있습니다. 이를 활용할 수 있는 대표적인 사례로는 이벤트 소싱(사용자 행동·클릭 등 추적), 센서 모니터링(디바이스 데이터 수집), 알림 시스템(사용자별 알림 기록) 등이 있습니다. ..

Redis 2026.03.31

Redisson의 tryLock은 Redis SETNX의 어떤 문제를 해결할까?

SETNX 명령으로 구현하는 분산락분산 환경에서 동시성을 제어해야 할 때, Redis의 SET 커맨드로 락을 구현할 수 있습니다.SET lock:key value NX EX 30 Redis는 싱글 스레드로 커맨드를 처리합니다. 여러 클라이언트가 동시에 SET NX를 보내더라도, Redis 내부에서는 하나씩 순서대로 실행됩니다. 따라서 동시성을 제어하기 적합합니다. SET은 Redis에 String 자료구조로 데이터를 저장할 때 사용하며, NX 옵션은 key가 존재하지 않을 때만 값을 설정합니다.따라서 먼저 요청한 프로세스가 key를 선점하고, 나머지는 실패하도록 구현할 수 있습니다.추가로 value에는 요청자를 식별할 수 있는 고유 값을 넣어, 해제 시 자신이 잡은 락인지 확인하는데에 활용할 수 있습니다..

Redis 2026.03.10

큐에 21억 개가 담기는데, 왜 요청이 거부될까?

배경 이번 글에서는 톰캣 설정을 건드리다가 생긴 의문, 학습한 내용을 정리해보고자 합니다. server: tomcat: threads: max: 200 톰캣 공식 문서를 보면 maxThreads의 기본값이 200개입니다.maxThreads: If not specified, this attribute is set to 200.그리고 톰캣은 Thread per Request 모델을 사용합니다. 요청 하나당 스레드 하나가 할당되는 방식입니다.The Connector creates a separate thread for each incoming HTTP request. 또한 스레드 풀 개수가 200개 일 때, 201번째 클라이언트(사용자)의 요청은 큐에서 대기한 후 스레드가 반환되면 처리된..

Tomcat 2025.12.03

Lambda로 파일 생성 서버 분리, DLQ로 운영 안정성 확보하기

배경지금까지 엑셀 생성 기능을 두 차례 개선했습니다.먼저 BlockingQueue를 활용해 이미지 다운로드를 병렬화했습니다. 순차 처리에서 병렬 처리로 전환하면서 다운로드 응답 시간을 단축했고 메모리 사용량도 제어할 수 있었습니다. 이어서 파일 생성을 비동기 스레드에서 수행하고 폴링으로 진행률을 제공했습니다. 사용자는 즉시 응답을 받고 진행률을 확인할 수 있게 되었습니다.하지만 Grafana로 모니터링하던 중 엑셀 생성 작업의 CPU 사용률이 20-30%임을 확인했습니다. 이는 피드백이 30개 쌓인 단체의 경우였고, 임의로 500개를 삽입한 뒤 다운로드 요청을 모니터링한 결과 CPU 사용률은 100%까지 상승했습니다. 파일 생성은 CPU 집약적인 작업이었고 이를 API 서버에서 처리하는 것은 적절하지 않..

Infra 2025.12.01

Transactional Outbox Pattern으로 비동기 작업 신뢰성 보장하기

배경두게더 서비스의 핵심 기능 중 하나는 챌린지 그룹 멤버들 사이의 상호작용입니다. 사용자가 투두를 완료하면 사진과 설명으로 인증을 요청하고, 같은 그룹의 다른 멤버가 그것을 검사해서 인정하거나 거절하는 방식입니다. 즉, 사용자는 투두 작성 → 인증 생성 → 알림 → 검사 이라는 흐름을 거치게 됩니다.알림을 통해 사용자들은 상호작용하며 챌린지를 이어가며, 인증 → 알림은 서비스에서 정말 중요한 기능이라고 할 수 있습니다. 현재 코드투두 인증 요청을 하게 되면 현재 다음과 같은 순서로 동작합니다.@Transactionalpublic void certifyDailyTodo( final Long memberId, final Long dailyTodoId, final String certify..

Project 2025.11.04

Blue-Green 무중단 배포 파이프라인 구축하기

"왜 이 작업을 해야 하나?"새로운 기능을 만들거나 개선할 때, 항상 이 질문부터 시작합니다. 기술은 문제를 해결하는 도구일 뿐이고, 도구를 먼저 고르는 건 올바른 순서가 아니라고 생각합니다. 피드줍줍 팀에서 무중단 배포 파이프라인을 구축하기로 결정한 과정도 마찬가지였습니다. 배포란 무엇일까?배포는 작성한 코드를 사용자가 실제로 사용할 수 있도록 만드는 과정입니다. 개발 환경에서 작동하는 애플리케이션을 운영 서버에 올리고, 사용자의 요청이 새 버전으로 전달되게 합니다.전통적인 배포 과정은 단순합니다.기존 서버를 중지새 버전을 배포서버를 다시 시작문제는 이 과정에서 서비스가 중단된다는 점입니다. 서버를 중지하는 순간부터 다시 시작할 때까지, 사용자는 서비스를 이용할 수 없습니다. 왜 무중단이어야 하는가..

Infra 2025.10.26

파일 다운로드 경험 개선: 비동기 작업 분리, Polling 기반 진행률 추적하기

배경이전 글에서 BlockingQueue 기반 이미지 다운로드 병렬 처리를 통해 성능을 개선했습니다. 이미지가 포함된 피드백 50개 (운영 서버 내 단체의 피드백 평균 개수) 기준으로 다운로드 시간을 5초에서 500ms로 단축하였고, 메모리 사용량도 안정적으로 제어할 수 있었습니다. 하지만 파일 생성 과정 전체로 보면 여전히 긴 시간이 소요됐습니다. 이미지 다운로드 외에도 피드백 조회, 엑셀 생성과 이미지 삽입, 디스크 flush 등 여러 단계를 거쳐야 했기에 결과적으로 전체 파일 생성에는 약 10초가 소요되었습니다. 여기서 문제는 이 10초 동안 사용자에게 아무런 응답을 주지 못한다는 것이었습니다. 사용자는 다운로드 버튼을 누른 후 서버에서 파일 생성이 완료되는 10초 간 응답을 받지 못하고, 파일이 ..

Project 2025.10.12

병렬 처리하면 무조건 좋을까? : BlockingQueue로 파일 다운로드 성능 & OOM 개선하기

배경피드줍줍 서비스를 운영하며 다음과 같은 피드백을 받았습니다.단체 관리자를 위해 피드백 데이터를 외부에서 활용 가능한 형태로 제공되면 좋겠음현재 웹 화면 만으론 데이터 분석, 보고서 작성, 외부 도구 연동이 어려움이를 해결하기 위해 관리자들이 수집한 피드백 데이터를 엑셀 파일로 내보내는 기능을 개발했습니다.피드백에는 이미지도 포함되어 있기 때문에 수십개의 이미지를 어떻게 안정적이게 다운받고 엑셀 파일에 첨부시킬지 고민하게 되었습니다. 기능은 아래와 같이 피드백 추출 버튼을 누를 시 엑셀 파일이 다운되도록 동작합니다. 다운을 받고 나면 위와 같이 피드백 데이터가 정리된 엑셀 파일을 볼 수 있습니다. 엑셀 생성 방식 선택먼저 자바에서 엑셀을 생성하는 방법에 대해 조사한 결과, 대표적으로 두 라이브러리가 있..

Project 2025.10.07

실시간 로그 모니터링 시스템 구축하기 (Alloy, Loki, Grafana)

파일 기반 로그의 한계이전 포스팅(https://yeong0jae.tistory.com/42)에서 Logback을 활용한 로깅 시스템을 구축했지만, 운영 환경에서 실제로 사용해보니 한계가 명확했다. "로그 파일을 직접 서버에 접속해서 봐야 한다고?" 피드줍줍 prod ec2에 매번 ssm으로 접속해서 tail -f app.log로 로그를 확인하는 것은 비효율적이었다. 특히 여러 서버가 있는 환경(dev, prod)에서는 각각 접속해서 확인해야 하는 번거로움이 있었다. 게다가 과거 로그를 검색하거나 특정 패턴을 찾는 것도 쉽지 않았다. "실시간으로 로그를 모니터링하고, 검색도 쉽게 할 수 있는 방법이 없을까?" 이런 고민 끝에 피드줍줍 팀에선 로그 모니터링 시스템을 구축하기로 결정했다. 로그 모니터링 ..

Infra 2025.08.03

로깅, 왜 해야할까?

새벽 3시에 울리는 장애 알림만큼 개발자를 괴롭히는 것이 또 있을까? 급하게 서버에 접속해서 원인을 찾아보려 하는데, 에러 스택 트레이스도 없고, 언제 어떤 요청에서 문제가 발생했는지도 알 수 없다. 이런 경험이 있다면, 왜 로깅이 필요한지 이미 몸소 체감했을 것이다. 로그는 단순히 개발할 때 디버깅용으로만 쓰이는 것이 아니다. 운영 환경에서 시스템의 상태를 파악하고, 장애를 빠르게 해결하며, 사용자 행동을 분석하는 핵심 도구다. 로깅이 필요한 이유1. 장애 대응의 핵심운영 환경에서 발생하는 문제들은 개발 환경에서는 재현되지 않는 경우가 많다. 네트워크 지연, 동시성 문제, 특정 데이터 조합에서만 발생하는 버그들... 이런 문제들을 해결하려면 그 순간의 상황을 기록한 로그가 유일한 단서가 된다.2. 성..

Spring 2025.08.02