2025/01 15

[ACE Hand Wash - 트러블 슈팅] Bootstrap 첫 걸음: JSP 충돌 해결 스토리

배경전자정부 프레임워크를 사용하여 세차장 관리 시스템을 개발하던 중, 각 JSP 파일에 헤더와 푸터를 포함하는 과정에서 JSP의 디렉티브 설정으로 인한 충돌 문제가 발생했습니다.문제 상황헤더와 푸터 분리 및 적용 과정공통 헤더(header.jsp)와 푸터(footer.jsp)를 별도의 파일로 분리한 뒤, 각 JSP 페이지에서 및 를 통해 호출했습니다.각각의 JSP 파일에 이미 디렉티브가 포함되어 있던 상태였습니다.발생한 에러기존 JSP 파일과 분리된 헤더/푸터 파일 모두 디렉티브를 포함하고 있었습니다.이로 인해 JSP 페이지가 실행되지 않으며, "두 개의 contentType이 설정되어 있다"는 충돌 에러가 발생했습니다.원인 분석JSP 파일마다 디렉티브가 중복되어 JSP 컨테이너(Tomcat 등)..

[library- 트러블 슈팅] 패키지 설치의 덫: GPG 인증 문제 해결기

문제AWS EC2 인스턴스에서 MySQL 설치를 진행하던 중 GPG 키 인증 오류가 발생하여 패키지 설치가 중단됨. RPM 패키지를 여러 번 다운로드했으나 동일한 문제가 반복 발생.원인GPG 키가 누락되거나 만료되어 MySQL 설치 시 패키지 인증이 실패한 것이 원인.해결 과정1. GPG 키 수동 추가sudo rpm --import  2. 이후 MySQL 설치 재시도sudo yum install mysql-community-server -y 3. GPG 체크 생략 옵션 사용    위 방법으로도 해결되지 않을 경우, GPG 체크를 생략하고 설치sudo dnf install mysql-community-server --nogpgcheck 3. MySQL 서비스 시작 및 상태 확인    MySQL 설치 후 서..

[library - 기술적 의사 결정] 프리 티어 한계를 넘어서: 메모리 부족과의 전쟁

문제AWS 프리 티어 환경에서 EC2 인스턴스(기본 1GB 메모리)를 사용 중, 스프링부트 애플리케이션 실행 시 메모리 부족으로 인해 성능이 저하되거나 애플리케이션이 비정상적으로 종료되는 문제가 발생.해결 방안 분석문제를 해결하기 위해 두 가지 방안을 고려:Swap 메모리 설정장점:비용 추가 없이 현재 인스턴스에서 메모리 부족 문제를 완화할 수 있음.설정이 간단하고 빠르게 적용 가능.단점:디스크 기반으로 메모리를 확장하므로 I/O 성능 저하 발생 가능.높은 트래픽 상황에서는 여전히 불안정할 수 있음.설정 방법인스턴스 업그레이드장점:CPU와 메모리 모두 확장 가능, 애플리케이션의 안정성과 성능을 보장.Swap 설정 없이 물리적 리소스 증가로 I/O 병목 문제 해결.단점:프리 티어의 무료 범위를 벗어나 추가..

[ACE Hand Wash - 기술적 의사 결정]코드 정리 대작전: 권한 확인 로직, 어디까지 분리해봤니?

배경현재 프로젝트에서는 UserVO를 세션에서 가져와 권한을 확인하는 로직이 컨트롤러 메서드마다 반복되고 있습니다. 이러한 중복은 작동에는 문제가 없지만, 유지보수성과 코드의 가독성을 저하시킬 수 있습니다. 특히, 반복된 로직을 수정해야 하는 경우 모든 메서드를 업데이트해야 하며, 이는 일관성 유지에 어려움을 초래할 수 있습니다.따라서, 권한 확인 로직의 중복을 제거하고, 재사용성과 유지보수성을 높이는 방향으로 개선을 진행하려 합니다.개선 방향1. 메서드 추출 방식권한 확인 로직을 별도 메서드로 분리하여 각 컨트롤러 메서드에서 이를 호출하도록 단순화할 수 있습니다.구현private boolean isAdmin(HttpServletRequest request) { UserVO userVO = (Use..

[CodeChef - 트러블 슈팅] 포인트 전쟁에서 살아남기! Redis로 실시간 속도 전투!

실시간 유저 랭킹 조회 DB에서의 조회와 Redis를 캐싱(Cacheable 사용)한 것에서의 비교분석 DB에서 유저 랭킹 조회 레디스에서 조회  위 그래프들을 표로 분석[내가 구현한 기능]포인트에 따른 실시간 유저 랭킹[주요 로직]실시간 유저 포인트 랭킹 기능에서 Redis의 Sorted Set 자료 구조와 TTL(Time to Live) 기능을 사용하여 빠른 조회 성능을 확보하고 데이터 일관성을 유지했습니다. Sorted Set을 통해 유저 포인트를 기준으로 자동 정렬된 상태로 랭킹을 관리하며, TTL을 설정해 캐시 데이터가 일정 시간이 지나면 자동으로 갱신되도록 구현했습니다.[배경]실시간 포인트 랭킹 조회 기능이 높은 트래픽 상황에서도 빠른 응답 속도를 유지할 수 있도록 최적화가 필요했습니다. 기존..

[CodeChef - 트러블 슈팅] 인덱싱: 데이터 속도 전쟁에서 살아남기!

[문제 인식]게시글 검색을 위해 풀 테이블 스캔을 하는건 너무 비효율적이고 성능 소비가 심하다.대량의 데이터가 생길수록 응답 속도는 더 큰 차이를 보인다. 그래서 풀 테이블 스캔이 아니라, 인덱스를 생성하여 데이터 조회 속도를 높이고, 리소스 사용을 최적화 한다.인덱스책의 색인처럼 특정 데이터를 빠르게 찾을 수 있도록 하는 특별한 데이터 구조이다.B-Tree 인덱스: 범위 검색, 정렬된 데이터 조회에 적합하여 대부분의 데이터베이스에서 기본적으로 사용된다.Hash 인덱스: 특정 값과 일치하는 데이터를 찾는 데 빠르며, 범위 검색에는 적합하지 않다.[선택 이유]검색 속도를 높인다: 인덱스가 있으면 특정 데이터 위치를 바로 찾아가니까 전체 테이블을 검색할 필요 없이 빠르게 결과를 얻는다.응답 시간을 줄인다: ..

[CodeChef - 트러블 슈팅] 실시간 알림의 비밀: RabbitMQ로 댓글 알림 시스템 구축하기

[내가 구현한 기능]사용자들이 게시글에 댓글을 작성할 때, 해당 댓글이 게시글 작성자에게 실시간으로 알림으로 전달되는 기능을 제공하기 위하여, 댓글 알림 기능을 WebSocket + Redis Pub/Sub에서 RabbitMQ와 WebSocket을 활용하여 실시간으로 전송하는 시스템을 구현했습니다. [주요 로직]댓글 생성 시 알림 발행: 댓글이 작성되면 해당 댓글 정보와 함께 게시글 작성자에게 알림을 보내도록 메시지를 발행합니다. RabbitMQ를 통한 메시지 라우팅: 댓글 알림 메시지는 RabbitMQ의 Direct Exchange를 통해 commentQueue에 라우팅됩니다. RabbitMQListener를 통해 WebSocket 전송: RabbitMQ의 commentQueue를 구독하는 Rabbit..

[CodeChef - 트러블 슈팅] EC2 독립 선언: 한 서버에 갇힌 서비스들을 해방하다.

[배경]EC2 분산 배포에 대한 설명현재 EC2 하나에 카프카, 엘라스틱서치, 레디스, 스프링부트 서비스를 모두 배포하는 구조에서, 해당 EC2 인스턴스에 장애가 발생하면 모든 서비스가 동시에 중단될 위험이 있습니다. 따라서 각 서비스를 개별 EC2 인스턴스에 배포하여 분산 및 고가용성을 보장할 필요성이 커졌습니다.[요구사항]각각의 서비스인 레디스, 카프카, 엘라스틱서치, 스프링부트를 각기 다른 EC2 인스턴스에 배포해야 합니다. 이를 통해 서비스 간 독립성을 보장하고, 한 인스턴스에 장애가 발생하더라도 다른 서비스는 정상적으로 동작할 수 있도록 하는 것이 목표입니다.[선택지]1. 각각 EC2에 배포각 서비스마다 별도의 EC2 인스턴스를 할당하여 배포합니다.장점:고가용성: 한 EC2에 문제가 생겨도 다른..

[CodeChef - 트러블 슈팅] 배포 지옥 탈출기: GitHub Actions로 만들어낸 자동화 천국.

[주요 로직]GitHub Actions 시나리오개발자가 main 브랜치에 푸시하면, GitHub Actions 워크플로우가 자동 실행된다. 해당 워크플로우는 다음 단계를 포함한다.리포지토리 체크아웃actions/checkout@v4를 통해 애플리케이션 코드 리포지토리를 체크아웃한다.EC2 SSH 설정EC2 연결에 필요한 EC2_HOST, EC2_USER, SSH_PRIVATE_KEY 환경 변수를 사용해 SSH 설정을 구성한다.SSH_PRIVATE_KEY를 파일로 저장해 SSH 접근 권한을 설정한다.자바 환경 구성actions/setup-java@v4를 사용해 자바 17 환경을 설치하고, Gradle 빌드를 위한 설정을 마친다.Gradle 빌드gradlew 파일에 실행 권한을 부여하고, ./gradlew ..

[CodeChef - 트러블 슈팅] 데이터 수호자들 : 동시성 이슈와의 싸움에서 살아남기.

동시성 제어 방식의 발전 과정 및 성능 분석이번 성능 테스트는 DB 바로 저장 방식에서 시작하여 낙관적 락, 비관적 락, 분산 락으로 발전하는 과정을 통해, 각 방식이 가진 성능적 특징과 개선 효과를 평가했습니다. 각 방식의 성능을 측정한 결과는 다음과 같습니다.DB 바로 저장 > 2. 낙관적 락 > 3. 비관적 락 > 4. 분산 락 순으로 개선하였으며, 각 방식의 주요 특징과 개선된 이유를 구체적으로 설명하겠습니다.1. DB 바로 저장DB 바로 저장 방식은 동시성 제어가 없이 여러 요청이 동시에 데이터베이스에 접근하는 방식입니다. 간단하게 구현할 수 있지만, 동시성 문제가 발생할 가능성이 큽니다.스레드 활성화 시간: 활성 스레드가 초반에 급격히 증가하다가 서서히 감소하는 경향을 보입니다. 여러 스레드가..