전체 글 58

Stack 이 무한이 커질 수 있다면, Heap 메모리는 불필요 할까?

이전 면접을 보던 중 여러 가지 질문을 받았지만, 그중 인상 깊었던 질문인 “Stack이 무한히 커질 수 있다면, Heap 메모리는 불필요할까?”에 대해 간단하게 정리하며 기록해 두고자 한다.이런 류의 질문은 정답이 있다기보다는, 질문을 받은 사람의 관점과 경험에 따라 답변의 깊이가 달라지는 생각을 필요로하는 질문이라고 생각한다. 때문에 해당 글에서는 다른 사람들의 모범 답안이 아닌 당시에 내가 이 질문에 어떻게 접근했고 어떤 논리로 질문을 풀어나갔는지 그 과정을 정리해 보려 한다.Stack 과 Memory이러한 질문에 답변하기 위해서는, 기본적으로 Stack과 Heap이 무엇인지 서로 간의 역할과 차이에 대해 알고 있어야한다.다만, 이 두 가지의 개념은 끝이 없을 정도로 깊기 때문에 모든 것을 설명하는..

카테고리 없음 2026.05.01

단순 for 문에서 Spring Batch + No-Offset 페이징까지

운영 중인 서비스에서는 외부 API 에 요청을 보내, 최대 하루에 한 번 사용자가 최초 발급받은 쿠키(인증 정보)가 유효한지 검증하는 백그라운드 작업이 필수적이었다.유효할 경우: 외부 API 요청을 통해 인증 정보를 갱신한다.유효하지 않을 경우: 내부 DB에서 해당 사용자의 인증 정보를 폐기한다. 이러한 작업은 서비스 초기, 인증 정보가 많지 않았을 때는 복잡한 구조가 필요하지 않았기에 스케줄러를 통해 모든 인증 정보를 한 번에 조회(SELECT ALL)하여 애플리케이션의 Heap 메모리에 적재한 뒤, 단순 for문을 돌며 관리하는 방법으로도 충분히 동작하였었다.하지만 서비스 사용자가 증가함에 따라 이러한 방식은 서버의 메모리 초과 위험성 증가로 이어지게 되었고, 작업 도중 일시적인 서버 장애가 발생하는..

카테고리 없음 2026.04.19

Stack, Heap Memory 기본 개념

프로그램이 실행될 때 메모리는 크게 스택과 힙 영역으로 나뉘어 사용되며, 두 영역은 관리 방식 및 사용 용도가 다름. 스택(Stack) 메모리LIFO 구조 ( 후입선출 ) , 마지막에 할당된 데이터가 가장 먼저 해제 (사용) 됨함수 호출 시, 자동으로 메모리가 할당되며 함수가 종료되면 자동으로 해제되는 방식. 기본적으로 OS 에서 스택 크기를 미리 할당하며, 접근 속도가 빠름JAVA 에서는 지역 변수를 저장, 함수 호출 스택, 리턴 주소를 저장하는 등 활용기존 지정한 스택의 크기를 초과하거나 재귀 함수 등으로 이러한 스택 메모리를 무한으로 호출할때 문제가 발생하기 때문에 주의 필요 힙(Heap) 메모리메모리 크기를 동적으로 결정할 수 있으며, 개발자 혹은 OS 등이 직접 메모리를 할당하고 해제할 수 있지..

카테고리 없음 2026.04.05

EC2 프리티어에서 로그 백업

진행하던 사이드 프로젝트에서 에러 추적을 위해 로그 내역을 백업하기로 하였다. 하지만 해당 프로젝트는 EC2 프리티어라는 제한된 환경에서 구동되었기에, 무거운 외부 인프라나 유료 솔루션 도입이 어려운 상황이었다. 이번 글에서는 제한된 환경 안에서 비용 없이 효율적으로 로그를 백업한 과정을 정리해 본다.[ 1. DB에 직접 저장하기 ]가장 먼저 떠올린 방법은 모든 로그를 사용 중인 DB에 저장하는 것이었다. AOP나 Filter 단에서 요청과 응답을 가로채 저장하기만 하면 되므로 구현이 매우 간단하다는 장점이 있었다. 하지만 이 방식에는 아래와 같은 문제점이 존재하였다.성능 저하: 매 요청마다 애플리케이션과 DB에 불필요한 I/O 작업이 발생하여 큰 부담을 주었다.용량 문제: 일정 개수 이상 쌓였을 때만 ..

카테고리 없음 2026.03.20

JPA 환경에서 MyBatis? JPQL? QueryDSL?

Springboot + JPA 환경에서 프로젝트를 개발하다 보면, 반드시 한 번쯤은 다수의 테이블을 Join 하여 특정 필요한 데이터만 조합해야 하는 경우가 반드시 찾아온다.이때, JPA 를 100% 활용하기 위해서는 연관된 모든 Entity 를 조회한 뒤 Getter 를 통해 필요한 정보를 추출하고 조합하는 방식을 활용할 수 있지만 이는 사용하지 않는 데이터까지 DB 에서 가져와야 하기에 트래픽이 증가되면 증가될 수록 DB와 어플리케이션 단에 불필요한 부담을 발생시키게 된다.물론, JPA 내부에서도 Projection 이라는 기능이 존재하여 이를 적절히 활용하여 해결할 수도 있겠지만 Join 이 복잡해지거나 동적으로 변하는 등 확장에 유연하게 대처하기 어려워 주로 아래 세 가지 선택지를 고려하게 된다...

카테고리 없음 2026.03.07

Private 서버 환경에서 CI/CD 구축 ( Github Action Runner 도입 )

이번 글에서는 보안 강화를 위해 개발 서버를 Public 환경에서 Private 환경으로 전환하며 발생한 CI/CD 배포 파이프라인의 문제점과, 이를 해결하기 위해 Github Action Runner를 도입한 과정을 정리한다. 1. 배경 및 문제점기존 CI/CD 아키텍처는 Github WebHook과 Jenkins를 활용한 구조였다. GitHub에서 Push 이벤트가 발생하면 WebHook을 통해 Jenkins 서버로 알림을 전달하고, Jenkins가 이를 감지하여 개발 서버에 배포하는 방식이었다. 하지만 기존 Public이었던 개발 서버를 Private 환경으로 변경하면서 외부에서의 인바운드 트래픽이 모두 차단되었고, 결과적으로 GitHub에서 보내는 WebHook 요청을 서버가 수신할 수 없는 상..

카테고리 없음 2026.02.18

0.5GB 메모리 환경, 로컬 캐시로 성능 최적화

이번 사이드 프로젝트에서는 한정된 리소스 환경에서 서비스를 운영하며 발생한 성능 저하 문제와, 이를 해결하기 위해 로컬 캐시(Local Cache)를 도입한 과정을 정리한다.1. 배경 및 문제점현재 프로젝트는 0.5GB 메모리를 가진 서버 2대(Spring Boot 1대, DB 1대)만을 활용해 운영해야 하는 상황이었다.이러한 제약은 Spring Boot와 DB 모두에 상당한 부담을 주었고, 특정 데이터를 조회하고 가공하는 과정에서 초 단위의 지연 시간이 발생하는 것을 확인할 수 있었다.원인을 분석한 결과, 이는 쿼리 자체의 비효율성보다는 순수 DB에 접근하는 I/O 과정에서의 오버헤드가 가장 큰 문제인 것으로 확인되었다. 때문에 DB 접근 자체를 최소화하거나, 아예 DB를 사용하지 않고 최적화할 수 있..

카테고리 없음 2026.02.08

MicroK8S ( 경량화 K8S )

경량화 K8s실무에서 Kubernetes(K8S) 도입에 앞서, 개인적으로 필요한 부분들을 먼저 학습하고 활용해두면 좋을 것다는 생각이 들었다.하지만, K8S 는 기본적으로 클러스터 환경을 전제로 설계된 만큼 제대로 테스트 하려면 여러 대의 서버가 필요했지만 개인 학습 환경에서는 온전한 K8S 를 구동하기에는 리소스가 너무 무거워 테스트 하기 버거운 문제가 발생하였다.그래서 경량화 K8S 로 눈을 돌렸고, 아래와 같은 대안들을 찾게 되었다.Minikube: 가장 대중적이고 레퍼런스가 많아 학습용으로 좋지만, VM/컨테이너 구조상 다른 경량화 툴에 비해 무거움.K3s: IoT/Edge를 위해 극한으로 경량화되어 가볍지만, 내부 구조(SQLite 등)가 표준과 달라 설정이 까다로울 수 있음.Microk8s:..

카테고리 없음 2026.01.25

[Spring Security] 비동기 환경에서의 인증 정보 전파와 트랜잭션 관리

1. 기존 아키텍처 및 프로세스현재 서버는 메인 서버와 수집 서버로 분리 되어, 메인 서버에서 특정 유저에 대한 정보가 필요할 때, 수집 서버에서 필요한 정보를 조합해 메인 서버로 요청을 보내는 구조를 가지고 있다. 이때 요청 방식은 크게 HTTP 요청과 메세지 큐(Message Queue)를 통한 발행 두 가지로 뉘었고, 식별 및 로깅 처리를 위해 메인 서버와 수집 서버 모두 어떤 사용자에 대한 요청인지 요청에 포함된 인증 정보를 파악하고 처리해야만 했다. 2. 문제점기존에 HTTP 요청만 존재했을 때는 Filter 단에서 인증 정보를 추출하여 검증하면 간단히 해결되었다. 하지만 메세지 큐를 통해 들어오는 요청은 Filter를 거치지 않기 때문에, 동일한 로직으로는 유저 정보를 추출할 수 없는 문제가 ..

카테고리 없음 2026.01.11

외부 API 연동 서비스의 안정성 확보

이번 프로젝트에서는 명확한 API 정의서나 가이드 조차 없는, 제약 사항이 많은 외부 API 를 활용하며 발생했던 동시성 이슈, DB 커넥션 고갈 문제, 그리고 이를 해결하기 위한 RabbitMQ → SQS 로 리펙토링 과정을 정리한다.1. 기존 아키텍처 및 프로세스시스템의 기본 구조는 메인 서버와 수집 서버가 메시지 큐를 사이에 두고 통신하는 형태다.[Architecture Flow]메인 서버는 수집에 필요한 정보를 담아 메시지를 발행한다.수집 서버는 해당 메시지를 수신하여 외부 API를 호출해 정보를 조회한다.조회 결과를 저장하고, 그 결과를 다시 메시지로 발행해 메인 서버에 반환한다.2. 문제점서비스를 운영하며 외부 API의 특성과 트래픽 증가로 인해 다음과 같은 문제들이 발생 하였다.2.1. 동시..

기술적 고민 2025.12.23