전체 글 38

CompletableFuture를 활용한 도서 베스트셀러 저장 성능 개선

개요  도서 인사이트 공유 프로젝트 `지성인`에는 베스트셀러 도서를 매일 최신화하는 로직이 존재한다.매일 오전 4시에 베스트셀러 상위 100권 정보를 크롤링하여 서버에 저장한다.처음에는 동기적인 방식으로 코드를 작성하여 작업을 수행했다.하지만 이 방법은 많은 시간이 소요되어 효율성에 문제가 있었다. 그래서 이 문제를 해결하기 위해 CompletableFuture를 활용한 비동기 처리와 병렬 프로그래밍으로 개선을 시도했다.이 글에서는 기존 동기적인 접근 방식에서 겪었던 지연 문제를 어떻게 해결했는지, 그리고 새로운 방법으로 얼마나 개선됐는지 공유해본다. 문제 상황@Component@RequiredArgsConstructorpublic class Yes24Crawler implements Crawler { ..

프로젝트 2024.10.24

RTR 방식과 Refresh Token을 Redis에 저장하는 이유

Token과 RTR 방식AccessToken: 사용자가 특정 서비스에 접근할 권한을 증명하는 문자열이다. 사용자의 인증 정보를 확인한 후 발급되며, 사용자가 서비스를 이용할 때마다 이 토큰을 사용해 자신의 인증 상태를 증명한다.RefreshToken: AccessToken을 재발급받을 때 사용하는 토큰이다. AccessToken의 만료 시간을 길게 설정할 경우, 탈취 시 악의적인 공격에 악용될 위험이 있다. 따라서 AccessToken은 짧은 만료 시간을 가지도록 하고, 대신 상대적으로 긴 만료 시간을 가진 RefreshToken을 사용해 새로운 AccessToken을 발급받도록 한다. 이를 통해 사용자는 로그아웃하지 않고도 지속적으로 로그인 상태를 유지할 수 있다.Refresh Token Rotatio..

데이터베이스 2024.10.14

RESTful한 path 설계하기

프로젝트를 리팩토링하며 처음에는 신경쓰지 않았던 API path들이 거슬리기 시작했다. 일단 REST API란 HTTP 프로토콜을 기반으로 서버와 클라이언트가 데이터를 주고받는 방식이다.주요 특징은 아래와 같다.리소스 기반HTTP 메서드 사용무상태성 (상태를 저장하지 않으며, 각 요청은 독립적)응답 방식 (JSON / XML) 그래서 도메인 엔티티들의 리소스를 어떻게 명시해야 RESTful하게 설계할 수 있을까 ?내가 고민했던 부분의 path는 다음과 같다. // 시작을 comments로 하는 경우POST /comments/talk-rooms/{talkRoomId} // 대화방에 댓글 작성GET /comments/talk-rooms/{talkRoomId} // 대화방의 모든 댓글 조회// 끝을 comme..

프로젝트 2024.10.05

Spring MSA 환경 배포 자동화에 대한 인프라 아키텍처 고민

해당 졸업 작품 주제를 구현하면서 겪은 내용을 정리 해보겠다.우리 팀은 밴드 모집/홍보 관련 웹 서비스를 기획하고 개발을 진행했다.하지만 졸업 작품은 클라우드/인프라 아키텍처가 핵심이라 서비스 기능 개발보다는 클라우드 아키텍처 구현에 집중했다.처음에 구상했던 아키텍처는 위 그림과 같다.이런 인프라 아키텍처를 구현해본 경험이 없어서 이상한 부분이 있을수도 있다 !간단하게 아키텍처를 설명해보겠다. 일단 비효율적일수도 있지만 팀원이 3명인지라 모두가 파이프라인을 구현하는 경험을 해보기 위해 Front/Back 레포를 나눴다.각각의 레포는 아래의 로직으로 동작한다.각 레포에 Push/Merge가 발생하면 Webhook으로 Jenkins에 알린다.Jenkins는 지속적 통합(Build, Test, Merge)을 ..

카테고리 없음 2024.09.07

24년 상반기 회고

원래 7월에 작성하려고 했지만.. 바빠져서 상반기 회고글을 8월에 작성하게 됐다.이왕 이렇게 된 거 23년 말부터 시작해보자. 🤭 많은 일이 있었지만 시작한다면 작년에 했던 동아리 큐시즘부터지 않을까 싶다.큐시즘 수료작년 8월 말부터 활동한 큐시즘에서 11월 밋업데이를 통해 진행해왔던 프로젝트를 마치고 수료했다.밋업데이란 ? 아이디어톤 행사를 통해 발제된 아이디어를 3개월 동안 준비, 구현해서 최종적으로 발표까지 하는 프로젝트다.우리팀은 대학교 제휴사업과 관련된 주제로 프로젝트를 진행했었다.  아쉽게 상은 수상하지 못했지만 함께 달려왔던 길들이 재밌었고 즐거웠다.또한 내가 이 동아리에 이 팀원들을 만나지 않았다면 다시는 해보지 못할 경험들이었다.A+ 팀 팀원들 모두 너무 수고했다. 큐시즘 마지막 행사에..

회고 2024.08.14

AOP를 통한 유저 인증 정보 미리 주입하기

개요카카오 소셜 로그인을 구현하고 토큰을 발급하여, 인증 정보를 토큰으로 관리하는 프로세스를 구현했다.Authentication 객체를 통해 인증된 유저 정보를 활용할 수도 있었다.하지만 해당 방법은 사용할 수 있는 유저 정보가 제한적이고, 중복되는 코드가 많아지는 단점이 존재한다.그래서 AOP와 Authentication 객체를 활용해서 메서드 호출 전에 유저 정보를 주입해보자. 구현CurrentUserInfo 유저 정보 주입을 통해 생성되는 객체이며, 실질적으로 비즈니스 로직에서 사용되는 객체다.현재 필요한 정보인 유저 ID만 존재한다. AssignCurrentUserInfo 해당 어노테이션이 달린 메서드만 호출 전에 유저 정보 주입이 실행된다. AssignCurrentUserInfoAspect 로직..

프로젝트 2024.07.23

[지성인] JaCoCo 테스트 분석 도구 적용, 프로젝트 테스트 커버리지 확인

약 1개월 반 전에 테스트 개수가 200개였다..  추가적인 기능 개발과 리팩토링을 했더니 단위 테스트도 늘어나서 55개가 늘어난 258개가 되었다.우리 백엔드 파트는 '지성인' 프로젝트를 시작할 때부터 모든 분기 테스트를 작성하기로 마음 먹었다. 또한 레이어드 아키텍처를 적용해서 각 레이어별 역할을 명확히 했다.그에 따라 각 기능에 대해서 레이어별로 단위 테스트를 작성했다.힘들긴 했지만 .. 테스트 코드 덕분에 통해 코드의 품질이 올라갔다고 생각한다. 이쯤되니 우리 프로젝트의 테스트 커버리지는 얼마나 되는지 궁금해졌다.그래서 GitHub Actions을 통해 JaCoCo 테스트 분석 도구를 적용하기로 했다. 적용build.gradleplugins { id 'java' id 'org.sprin..

프로젝트 2024.07.09

[지성인] 한줄평 좋아요 중복 생성 동시성 문제

지성인 프로젝트를 개발하면서 한줄평 좋아요 기능에 동시성 문제를 발견했다.일단 한줄평 기능은 특정 도서에 대해 짧게 평가할 수 있는 기능이다.해당 한줄평은 다른 사용자가 좋아요를 누를 수 있다. 문제 상황 현재 사이트에서는 좋아요를 1번 누르면 하트가 표시되고 다시 누르면 좋아요가 해제된다.또한 본인의 한줄평에는 좋아요를 할 수 없다. 보기에는 문제가 없어보인다.하지만, 좋아요를 광클해서 같은 요청이 한번에 보내진다면 ?악의적인 사용자가 요청 로직을 알아내서 똑같은 좋아요 요청을 한번에 보낸다면 ?서버에 심각한 에러가 발생할 수 있다. 해당 로직은 발생할 수 있는 문제 상황이다.왜 문제가 발생하는가 ? 임계 영역(Critical Section)에 경쟁 상태(Race Condition)가 발생하기 때문이다..

프로젝트 2024.07.06

STOMP로 소켓 방식 채팅 구현 + Rate Limiter, Token Bucket으로 API 처리율 제한하기

소켓 프로그래밍으로 채팅 애플리케이션을 구현해보자.그리고 Rate Limiter와 Token Bucket 방식의 API 처리율 제한기를 적용해보자. ⚡️ 채팅 애플리케이션 일단 STOMP는 텍스트 기반의 메시징 프로토콜로, 주로 메시지 브로커와 클라이언트 간의 통신을 위해 사용된다.메시지의 송수신을 담당하며, 클라이언트가 구독한 주제에 대해 응답을 받을 수 있도록 해준다.웹 애플리케이션에서 채팅, 실시간 업데이트, 알림 등을 구현할 때 많이 사용된다.  해당 그림을 살펴보면 발행-구독 매커니즘으로 특정 주제에 메시지를 보내면, 해당 주제를 구독하고 있는 subscriber 모두에게 메시지가 전달되는 구조다.  💫 애플리케이션 구조 해당 채팅 애플리케이션은 크게 두 가지의 Controller가 존재한다...

Spring 2024.06.21

Redis Sorted Sets으로 인기 검색어 구현하기

# Event프로젝트의 요구사항 중 검색칸을 눌렀을 때, 인기 검색어 보여줘야 했다. 처음에는 ElasticSearch를 이용해서 구현하고 싶었지만 알아야 할 내용이 너무 많았다.그래서 일단 MVP 구현을 위해 차선책으로 Redis의 Sorted Sets을 사용했다. 왜 차선책인가 ?DB보다는 Redis가 더 좋을 것이라는 것은 자명하다.만약 검색어를 DB에서 쿼리로 가져온다면 하드디스크 기반의 저장 공간에 접근해야 한다.하지만 Redis는 In-Memory DB이기 때문에 더 빠를 수밖에 없다. 또한 Sorted Sets을 통해 요청 검색어의 점수를 1씩 증가시킨다.조회할 때는 점수 Top-10을 반환한다. # Implementation@Configuration@RequiredArgsConstructo..

Spring 2024.04.09