반응형 Spring/Issue20 STOMP와 RabbitMQ를 이용한 채팅 서비스 이전 포스팅에서 STOMP를 이용한 채팅서비스를 개발했었다. https://miiro-under.tistory.com/273 Stomp를 활용한 웹소켓 구현 서론 Stomp를 이용하여 웹소켓을 구현하는 방법에 대해 알아보겠습니다. 이전 포스팅에서 Stomp에 관한 개념에 대해 설명했었습니다. https://miiro-under.tistory.com/272 Message Broker STOMP 개념 서론 Message를 miiro-under.tistory.com 여기서 간단히 정리를 하자면 STOMP 는 publish/subscribe(발행/구독) 구조로 간단하게 메시지를 선택해서 수신을 할 수 있다. 기본적으로 스프링에서는 내장 브로커를 제공하지만, 여러 문제점이 있다. 1. In Memory 형식으로 .. Spring/Issue 2024. 1. 30. QueryDsl을 이용한 페이지네이션 성능 개선 Issue 아래의 코드는 페이지네이션 을 구현한 예시이다. 아래의 코드를 직역하면 채팅방(Chatroom) 를 fetch join 하여 채팅방 참여자(ChatParticipant)를 생성 날짜를 최신 기준으로 페이징 처리한 것을 나타낸 것이다. 이를 바탕으로 @Query 어노테이션을 사용하는 JPQL 이 아닌 객체 지향 쿼리 중 하나인 QueryDsl 을 이용하여 변환을 진행하려고 한다. @Query("SELECT cp FROM ChatParticipant cp " + " JOIN FETCH cp.chatRoom cr " + " WHERE cp.member.id = :memberId" + " ORDER BY cr.createdAt DESC ") Page findAllByMemberId(@Param("me.. Spring/Issue 2024. 1. 27. [JPA] fetch-Join을 이용한 N+1 문제 해결 JPA를 사용하면 자주 만나게 되는 것이 N + 1 문제이다. N + 1 문제는 성능에 큰 영향을 줄 수 있기 때문에 N + 1 문제가 무엇이고 어떤 상황에 발생되는지, 어떻게 해결하면 되는지에 알아보겠습니다. JPA N+1 문제란? N + 1 문제란 1번의 쿼리를 날렸을 때 의도하지 않은 N번의 쿼리가 추가적으로 실행되는 것을 의미한다. When 언제 발생하는가? - JPA Repository를 활용하여 인터페이스 메소드를 호출할 시에(Read 시) Who 누가 발생시키는가? - 1:N 또는 N:1 관계를 가진 엔티티를 조회할 때 발생 How 어떤 상황에 발생되는가? - JPA Fetch 전략이 EAGER 전략으로 데이터를 조회하는 경우 - JPA Fetch 전략이 LAZY 전략으로 데이터를 가져온 이.. Spring/Issue 2024. 1. 26. Stomp를 활용한 웹소켓 구현 서론 Stomp를 이용하여 웹소켓을 구현하는 방법에 대해 알아보겠습니다. 이전 포스팅에서 Stomp에 관한 개념에 대해 설명했었습니다. https://miiro-under.tistory.com/272 Message Broker STOMP 개념 서론 Message를 송-수신할 때 사용하는 MessageBroker 중 STOMP 프로토콜에 대해 알아보겠습니다. STOMP란? Simple Text Oriented Messaging Protocol 의 약자로써, WebSocket의 서브 프로토콜 입니다. 웹소켓은 Text와 Bina miiro-under.tistory.com Stomp를 이용해서 간단하게 채팅 서비스를 구현해보겠습니다. 코드 구현 의존성(build.gradle) dependencies { //w.. Spring/Issue 2024. 1. 24. SMTP 비동기로 보내기(@Async) ISSUE 회원가입을 할 때 이메일을 통해서 인증을 하고 있다. 하지만 SMTP는 외부서비스이며 실제로 굉장히 느리다. HTTP 요청을 보내고 완료까지 시간이 오래된다면, 이메일 인증을 하는 유저 입장에서는 인증받는데 딜레이가 걸리게 된다. 기존 내용 코드 내용은 다음과 같다. 현재 코드는 인증코드를 랜덤으로 작성해서 MimeMessageHelper를 이용하여 코드 정보와 메일 내용을 작성한 후에 JavaMailSender를 이용해서 메일을 발송한다. 아래 있는 redis의 경우에는 이메일 정보를 이메일의 만료시간까지 저장하고 있다가 유효성 검증 시에 사용한다. HTTP 요청을 받으면 요청 시 Dto로 인증번호와 해당 이메일을 반환받도록 설정이 되어있다. 이메일을 인증하는데 14초 가 걸리는 문제가 있기.. Spring/Issue 2024. 1. 9. JPA Persistable 로 엔티티 구별하기 토이프로젝트 진행 중 OpenAPI의 값을 데이터베이스에 저장하고 특정 주기에 기존 값과 다른 경우 update를 하는 로직을 구현하려고 했습니다. 많은 데이터를 특정 주기(Scheduler)에 맞게 하나의 로직에서 DB 저장과 업데이트를 동시에 해야했다. 이를 바탕으로 자료를 찾아보던 와중에 Spring Data JPA 에서 지원하는 Persistable 을 알게 되었고 해당 구현체를 사용하는 방법에 대해 알아보겠습니다. Spring Data JPA save() 로직 Spring Data JPA가 제공하는 공통 인터페이스의 구현체인 SimpleJpaRepository 클래스에 있는 save() 메소드는 다음과 같다. entityInformation.isNew(entity) 를 통해 TRUE = pers.. Spring/Issue 2024. 1. 8. Scheduler Thread Pool 사용하기 이전 글에서 스프링에서 스케쥴링을 하는 내용을 다뤘다. https://miiro-under.tistory.com/261 레디스와 스케쥴러를 이용한 조회수 증가 Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션(Session)을 사용했다. https://miiro-under.tistory.com/260 조회수 기능 구현하기 - 중복 방지(Session) Issue 이전 포스팅에서 조회수 기능을 중 miiro-under.tistory.com 스케쥴링을 실행되어야 할 기능이 여러 개일 경우 사용해야할 것이 Thread Pool 이다. 위의 프로젝트에서 스케쥴러를 2개를 사용할 예정인데 예제를 이용하여 테스트를 진행해보겠습니다. 예제 코드는 해당 링크에서 확인하시면됩니다 : github 코드.. Spring/Issue 2024. 1. 8. @RequestParam을 Enum 타입으로 받기 축구 커뮤니티 프로젝트를 구현시 발생한 이슈입니다. 링크 : github 현재, Soccer 필드에는 Enum으로 관리되는 League 필드가 있습니다. 저는 League를 Request Parameter로 입력받아 Leauge에 해당하는 해당 정보들을 반환하는 GET 요청 API를 만드려고 합니다. League라는 Enum class에는 나라의 이름과 해당 나라 코드를 선언해놓은 상태입니다. 그러다보니 일일이 code나 country 를 request 요청을 하는 것보다 League enum을 변환하여 사용하고 싶다는 생각을 했습니다. 문자열과 enum의 이름이 같다면 자동으로 컨버팅해주겠지만, 그렇지 않다면 문제가 있습니다. 1. 휴먼 에러가 발생하기 쉽다. 2. 팀 프로젝트의 경우 중간에 참여한 사.. Spring/Issue 2024. 1. 7. [SpringBoot] Redis Hash 구조로 변경하기 Issue 이전 포스팅에서 레디스와 스케쥴러를 이용해서 DB에 주기적으로 업데이트를 진행했다. https://miiro-under.tistory.com/261 레디스와 스케쥴러를 이용한 조회수 증가 Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션(Session)을 사용했다. https://miiro-under.tistory.com/260 조회수 기능 구현하기 - 중복 방지(Session) Issue 이전 포스팅에서 조회수 기능을 중 miiro-under.tistory.com 해당 로직에 대한 피드백을 받았는데, 기존에는 redisService.hasKeys(VIEW_PREFIX + "*") 연산을 진행했었다. 해당 연산은 VIEW_PREFIX 라는 키를 가진 모든 키를 로드하는 방식.. Spring/Issue 2024. 1. 5. [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported] 에러 해결하기 DTO와 MultipartFile을 요청하는 create 로직에서 해당 에러가 났다. @RequestBody에서 @RequestPart로 어노테이션을 바꿔주고 @RequestPart(required = false) 와 함께 MultipartFile files 를 추가해준 상황이었다. 포스트맨에서는 내가 작성한 커스텀 에러가 나서 인텔리제이의 콘솔창을 확인해봤습니다. 에러 문구를 확인해보면 'Content-Type 'application/octet-stream' is not supported' 로 미디어 타입이 잘 못 되었다는 것을 확인할 수 있다. 원래는 file을 받기 전에는 포스트맨에서 raw -> Json 타입으로 데이터를 전송했었다. 하지만 file을 보내주면서 form-data 형식으로 변경해준.. Spring/Issue 2024. 1. 5. 레디스와 스케쥴러를 이용한 조회수 증가 Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션(Session)을 사용했다. https://miiro-under.tistory.com/260 조회수 기능 구현하기 - 중복 방지(Session) Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션 쿠키(Session-Cookie)를 사용했다. https://miiro-under.tistory.com/259 조회수 기능 구현하기 - 중복 방지(Cookie) Issue 커뮤니티 서비스를 구현 miiro-under.tistory.com 현재 로직의 경우 게시글을 조회할 때마다 DB에 조회수를 증가하는 카운팅을 쓰는 작업을 수행하고 있습니다. 하지만 조회수만 증가를 시키는 게 목적인데, 요청마다 테이블을 조회해서 불필요한 쿼.. Spring/Issue 2024. 1. 3. 조회수 기능 구현하기 - 중복 방지(Session) Issue 이전 포스팅에서 조회수 기능을 중복 방지할 수 있도록 세션 쿠키(Session-Cookie)를 사용했다. https://miiro-under.tistory.com/259 조회수 기능 구현하기 - 중복 방지(Cookie) Issue 커뮤니티 서비스를 구현하는 토이프로젝트를 진행하면서 게시판의 조회수를 증가 로직을 만드려고 합니다. 게시글이 조회될 때마다 조회수를 증가하는 게 가능하지만 동일 사용자에 한해 miiro-under.tistory.com 세션 쿠키는 사용자가 웹 사이트를 탐색하는 동안 생성되고 유지되며, 브라우저가 닫히면 삭제가 된다. 그런데 현재 나는 RESTful API를 구현하는 시나리오로 해당 토이프로젝트를 진행 중이다. RESTful API의 경우, 클라이언트와 서버 간 통신이.. Spring/Issue 2024. 1. 2. 이전 1 2 다음