[트러블 슈팅] ⚠️ 게시글 검색 및 페이지네이션 슬로우 쿼리
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
자유 게시판 프로젝트 진행 중 검색 기능을 구현한 뒤였다. 해당 프로젝트에는 더미데이터 약 2000천만건이 들어가 있었고, 게시글 첫 페이지 조회 시에만 해도 5초 이상이 걸리며 만약 맨 마지막 페이지의 컨텐츠를 확인하기 위해서 limit 20에 offset 20000000을 주게 될 경우 타임아웃이 발생하는 에러를 마주하게 되었다.... 이는 MySQL의 물리 디스크에 접근하여 데이터를 찾는데 그만큼 오래 걸린다는 것인데 이를 해결하기 위해서는 인덱스 생성이 필요해 보였다.문제 원인 파악원인을 파악하기 위해서 EXPLAIN 명령어로 해당 쿼리를 분석.확인 결과 type이 ALL인 것을 확인했다. 이는 쿼리가 인덱스를 사용하지 않고 풀 테입블 스캔을 하고 있음을 의미한다.게다가 총 1987만건의 데이터에..
[학습 포인트] 💡Redis SortedSet을 활용한 실시간 인기글 구현하기
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
자유 게시판 프로젝트를 진행함에 있어서 실시간 인기글을 구현해야 했다. 인기글 선정은 게시글의 좋아요와, 조회수, 그리고 댓글의 수를 따져가며 인기글인지 아닌지를 선정하게 되는데 여기에 있어서 Redis를 사용했다. 결정적인 이유는 자동 정렬 기능으로 인해 조회해 올 시 속도가 빠르다는 것이다. 인기글 조회는 사용자가 많이 접근하는 기능이기도 할 것이고, 그만큼 빠른 속도가 중요하기 때문에 채택하게 되었다. 인기글 선정을 RDBMS로 선정하고 저장해서 가져오게 될 경우 쿼리를 통해 조회해야 한다. 이 경우 인덱스를 활용하여 정렬과 조회 속도를 개선할 수 있겠지만, 새로운 인기글이 선정될 때마다 정렬 작업이 매번 이루어지게 되고 트래픽이 많아질 수록 DB 부하가 증가할 것이기 때문에 NoSQL DB인 Re..
[학습 포인트] 💡Redis를 활용한 toggle(좋아요)기능 구현하기
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
자유 게시판 프로젝트를 진행함에 있어서 게시글의 좋아요 기능과 댓글의 좋아요 기능을 구현함에 있어서 적절한 방법은 무엇일지 고민했었다. 기본적으로 한번 누르면 좋아요가 증가하고 한번 더 누르면 좋아요가 감소해야된다. 일반적으로 MySQL과 같은 RDBMS들은 쿼리가 발생하는 DB에 게시글의 좋아요 기능 혹은 댓글의 좋아요 기능을 구현함에 있어서는 select 쿼리와 update 쿼리가 발생하게 될 것인데, 이에 따른 동시성 문제를 어떻게 해결하고, 응답속도 최적화를 하기 위해서는 어떤 방법이 있을지 고민하다가 NoSQL인 Redis를 활용하기로 결정하였다. Redis를 사용하면 단일 스레드로 동작하기 때문에 증가, 감소, 삭제와 같은 명령어는 모두 Atomic하게 실행되므로 동시성 문제를 해결하기 위해서..
[학습 포인트] 💡Mockito Matchers와 실제 값을 이용한 테스트의 차이
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
레이어드 아키텍처의 단위 테스트 코드를 작성하다보면 Mock과 AssertJ를 사용하여 값을 검증하는 테스트 코드를 작성하게 된다. 이 때 테스트 코드 입문과정 시 헷갈리는 부분들을 정리하여 작성하게 되었다. 해당 테스트 코드는 BDD 스타일로 작성된 코드이다. 메서드의 호출 여부가 중요한 경우 - then()입력값이 중요하지 않고 메서드의 호출 여부만 확인하고 싶을 때가 있다.@Test @DisplayName("해당 메서드가 실제로 호출 되었는지 확인할 때") void callMethod() { //given given(mockService.process(anyString(), anyInt())) .willReturn(mock(Mocking..
[학습 포인트]💡 MockMvc 컨트롤러 단위 테스트 시 인증정보 부재
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
SpringSecurity를 사용하는 프로젝트에서 만약 Contrller의 단위 테스트 작업을 진행할 경우, 사용자의 인증정보가 필요하게 될 것이다. 해당 인증정보를 어떻게 Mocking하는지에 대해서 알아보자문제원인MockMvc로 Controller Layer 단위 테스트시에 SpringSecurity가 활성화된 상태에서 MockMvc.perform() 호출 시 인증 정보가 주입되지 않으면 기본적으로 403 Forbidden 오류가 발생한다.TestingAuthenticationToken 이나 커스텀 토큰으로 인증 객체 생성시에 필요한 권한 정보가 설정되지 않으면 Security 인가 과정이 실패한다.해결 방안@WithMockUser 또는 SecurityMockMvcRequestPostProcessor..
[학습 포인트] 💡Redis 단위 테스트 작성하기 feat.ValueOperations, Operations
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
ValueOperation이란?ValueOperations는 SpringDataRedis에서 StringRedisTemplate를 통해 Redis의 “Value”관련 연산을 수행하는 인터페이스이다.Redis에서 key-value형식으로 데이터를 저장하는데 이 때 ValueOperations는 Redis의 “String 타입” 데이터를 다루는데 사용된다.ValueOperations의 주요 역할데이터 읽기 작업String value = redisTemplate.opsForValue().get("key");데이터저장redisTemplate.opsForValue().set("key", "value");숫자증가redisTemplate.opsForValue().increment("counter");숫자감소redis..
[트러블 슈팅] ⚠️A component required a bean named 에러 원인
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
A component required a bean named 'redisTemplate' that could not be found.자유 게시판 프로젝트를 진행하던 중 나는 조회수와 댓글의 좋아요를 관리하기 위해 NoSQL 데이터베이스인 Redis를 사용했다. 사용하던 와중에 Redis의 데이터베이스를 관리하던 도중 위와 같은 에러가 발생했다.왜 redisTemplate 오류가 났었는가?해당 에러는 Spring이 redisTemplate라는 이름의 bean을 찾지 못했기 때문에 나타나는 에러이다.혹시 해당 프로젝트에서 redis의 데이터베이스를 나눠서 사용하는 프로젝트라면 해당 문제가 발생할 수도 있다.문제 상황이번 프로젝트에서 조회수를 관리하는 viewCount와 댓글의 좋아요를 commentLike가..
[트러블 슈팅] ⚠️ 읽기 전용 트랜잭션 내 쓰기 작업 문제와 REQUIRES_NEW 전파 전략 활용
·
프로젝트 트러블 슈팅 및 몰랐던점 정리/CommunityAPI
문제 상황Spring Boot + Spring Data JPA 환경에서 다음과 같은 코드가 있었다@Transactional(readOnly = true)public Post readById(Long postId, Long userId) { PostEntity post = postRepository.findById(postId).orElseThrow(() -> throw new RuntimeException("...")) viewCountService.increase(post.getPostId, userId); ...}클라이언트가 게시글을 조회할 때 조회수가 증가하는 로직이다. 해당 메서드에서는 읽기 전용 @Transactional 이 발생한다. 그리고 increase 메서드 내부viewCou..
cheolhyeon
'프로젝트 이슈 및 몰랐던점 정리' 카테고리의 글 목록