전체 글 41

RedisConnectionException 에러

필자는 도커이미지를 통해 api 인스턴스를 업데이트하고 있다. 최신 이미지를 pull하면 RedisConnectionException라는 에러가 뜨면서 수강신청을 실패하는 에러를 확인할 수 있었다. 1. RedisConnectionException이란?RedisConnectionException은 Redisson 클라이언트가 Redis 서버와의 연결을 확보하지 못했을 때 발생하는 런타임 예외이다.RuntimeException을 상속하며, 컴파일 타임에는 잡히지 않고 실행 시점에 발생한다. 연결 타임아웃의 규칙Redisson은 명령을 보내기 전에 커넥션 풀에서 연결을 하나 얻어와야 한다. 풀에 쓸 수 있는 연결이 없으면 그 자리에서 새로 TCP 연결을 맺는데, 이때 connectTimeout 안에 핸드셰이..

ArrayIndexOutOfBoundsException 에러

Sentry를 도입 후 일상생활을 보내던 중, 하나의 에러가 Slack에 왔다. 1. ArrayIndexOutOfBoundsException이란?ArrayIndexOutOfBoundsException은 Java에서 배열의 유효하지 않은 인덱스에 접근할 때 발생하는 런타임 예외이다. RuntimeException을 상속하며, 컴파일 타임에는 잡히지 않고 실행 시점에 발생한다. 배열의 인덱스 규칙Java에서 배열은 고정 크기이며, 인덱스는 0부터 시작한다.int[] arr = new int[5]; // 크기 5, 유효 인덱스: 0 ~ 4arr[0] = 10; // OKarr[4] = 50; // OK (마지막 인덱스)arr[5] = 60; // ArrayIndexOutOfBoundsException..

광클스탑 서비스를 혼자 운영해보며 느낀 회고록 (ep.01)

필자는 올해 대학교를 졸업한 백엔드 개발자 꿈나무입니다. 현재 웹 서비스를 혼자 개발 및 운영하며, 실제 트래픽 환경에서의 트러블슈팅 역량을 키우는 데 집중하고 있습니다. 이 글은 프로덕션을 운영하며 느낀 점에 대한 기록입니다.왜 이 프로젝트를 만들게 되었는가? 저는 수강신청에 지독히도 소질이 없는 학생이었습니다. 졸업 학점 130학점 중 90학점을 교수님을 통해 서면 신청으로 채워야만 했습니다. 마지막 학기마저 수강신청을 실패한 직후, 나와 같은 어려움을 겪는 학생들의 불편함을 직접 해결하고자 기획부터 런칭까지 단숨에 실행에 옮겼습니다. 일상생활의 불편함을 기술로 해결하는 것, 그것이 이 프로젝트의 첫 출발이었습니다.서비스 런칭 전, 시장성과 가치 검증 서비스를 런칭하며 가장 중요하게 고려한 것은 시장..

Spring Batch 병렬 처리 중 데이터 누락 문제 분석 및 해결

Spring Batch를 통해 17개의 CSV 파일을 병렬 파티셔닝 방식으로 DB에 적재하는 과정에서 데이터 누락 현상이 발생하였다.Spring Batch란? 각 파일을 개별적으로 적재할 경우 행 수가 일치하지만, 여러 파일을 동시에 병렬로 적재할 경우 총 행 수가 일치하지 않는 문제가 발생했다.테스트 결과테스트 대상 CSV 파일 행 수단일 CSV 적재 결과병렬 처리 시 두 파일을 동시에 적재한 결과데이터 누락 발생같은 조건에서 2번째 CSV 파일만 단독으로 적재하면 정상적으로 모든 데이터가 들어가는 현상이 확인되었다.⇒ 병렬 처리 상황에서만 데이터 누락이 발생하는 것을 의미한다.원인 분석JPA 쓰기 시점의 Flush 타이밍 이슈JPA는 persist() 후 트랜잭션 커밋 직전 flush()를 수행하여 ..

카테고리 없음 2025.05.12

트랜잭션이란?

트랜잭션이란?하나의 작업을 위해 더이상 분할될 수 없는 명령들의 모음.즉, 한꺼번에 수행되어야 할 일련의 연산 모음을 의미함예시:A는 매달 부모님에게 생활비를 송금 받는다. 어느날 처럼 부모님은 A에게 생활비를 보내러 ATM기에 갔고, 돈을 송금했다.하지만, 모종의 이유로 인해 부모님 계좌에선 생활비가 차감 되었는데, A의 계좌에는 생활비가 입금되지 않았다.위 계좌이체라는 행위는 인출과 입금 두 과정으로 이루어진다.⇒ 따라서 두 과정은 동시에 성공하거나 실패해야한다.위처럼 인출은 성공했지만, 입금이 실패하면 치명적인 결과가 나온다.즉, 이 과정을 동시에 묶는 방법이 바로 트랜잭션이다.START TRANSACTION -- 이 블록안의 명령어들은 마치 하나의 명령어 처럼 처리됨 -- 성공하던지, ..

Spring Batch란?

Spring Batch란?대량 데이터 처리를 위한 프레임워크이다.CSV 파일, DB, API 등에서 데이터를 읽고, 가공하고, 저장하는 배치 작업을 쉽게 구현할 수 있도록 도와준다.특히, 안정성, 재시작 가능성, 병렬 처리가 강점이다.Spring Batch의 구조Spring Batch는 Job, Step, Chunk라는 계층 구조로 동작한다.Job전체 배치 작업의 큰 틀, 여러 Step으로 구성된다.예시: “상가정보 데이터를 정제하고 DB에 저장하는 작업”StepJob 안의 개별 단계. 데이터를 읽고(Read), 처리하고(Process), 저장(Write)하는 단위.예시: “CSV 읽기 → 데이터 검증 → DB 저장”ChunkStep 안에서 데이터를 처리하는 단위. 한 번에 N개 데이터를 읽고 처리한 후..

RabbitMQ + Celery를 이용한 비동기처리로 사용자 경험 개선!

들어가며안녕하세요. 현재 유망한 백엔드 개발자를 꿈꾸는 진기태입니다.이번 포스팅에서는 AI 설계 생성 기능의 비동기 처리 리팩토링 과정을 공유하고자 합니다.기존 동기 방식으로 구현했던 기능을 RabbitMQ, Celery을 활용하여 비동기 처리로 전환하여 성능을 크게 개선한 사례를 소개합니다.동기 처리 vs. 비동기 처리: 문제 인식동기 방식 구현초기 구현 시, AI 설계 생성 기능은 동기적으로 작동하여 10회 호출 기준 3개의 정보를 생성하는 데 약 62초 정도 소요되었습니다.동시 다발적인 요청이 들어오는 상황에서 응답 지연 및 시스템 부하가 발생할 우려가 있었고, 이를 개선하기 위해 비동기 처리 방식으로 전환할 필요성을 느꼈습니다.문제점높은 응답 지연 시간: 요청마다 순차적으로 처리되어 전체 소요 시..

[자료구조] 스택(Stack)이란?

스택(Stack)이란?"쌓다", "쌓아 올리다"라는 뜻의 용어로, 데이터를 저장하고 관리하는 선형 자료 구조이다.LIFO(Last In, First Out) 형태로 마지막에 들어간 데이터가 가장 먼저 나오는 특성을 가지고 있다.예시로 접시나 상자 쌓기와 유사한 형태라고 생각하면 된다. 스택의 주요 특징은?LIFO(Last In, First Out)가장 마지막에 추가된 데이터가 가장 먼저 제거된다.한쪽 끝에서만 작업 수행데이터 삽입, 삭제가 스택의 맨 위(top)에서 이루어진다. 스택의 주요 연산은?1. push or add스택에 데이터를 추가한다.Stack stack = new Stack(); stack.push(10); // 스택에 10 추가stack.add(20); // 스택에 20 추가..

[백준 - JAVA] 28278 - 스택2

스택을 입문하기 좋은 매우 쉬운 문제다! 필자는 3년 전 C++로 코딩테스트 문제를 많이 풀었을 때, 거의 대부분 배열을 stack, vector으로 구현했었다.그래서 그런지 오랜만에 회고하는데도 큰 무리 없이 쉽게 푼 것 같다! 메모리 제한과 시간제한은 충분하다고 판단했다!  나의 구현 로직이다1 X: 정수 X를 스택에 넣는다. (1 ≤ X ≤ 100,000) -> push2: 스택에 정수가 있다면 맨 위의 정수를 빼고 출력한다. 없다면 -1을 대신 출력한다. -> pop3: 스택에 들어있는 정수의 개수를 출력한다. -> size4: 스택이 비어있으면 1, 아니면 0을 출력한다. -> empty5: 스택에 정수가 있다면 맨 위의 정수를 출력한다. 없다면 -1을 대신 출력한다. -> peekfor 문 사..

[백준 JAVA] 1427 - 소트인사이드

쉬운 문제였다! 로직을 생각해봣을 때, 무언가 int형 배열을 쓰는 거 보다 String으로 문자를 입력받아 charAt()을 사용하여 Character 배열로 내림차순 하는 게 낫다고 생각했다! 시간제한과 메모리제한은 n이 1,000,000이란 점에서 걱정했지만 2초라는 점에서 O(n^2)까진 가능할 거라고 판단했다. 내가 생각한 로직이다.1. string으로 문자를 받음2. 해당 문자를 charAt()으로 다시 배열로 변경3. 해당 n의 크기가 1억개이니 Collections.sort(); -> Collections.sort는 O(n log n)을 보장하기 때문! [최종 코드]import java.io.*;import java.util.*;public class Main { public stat..