전체 글 28

DB 접근 기술 이해하기 - JDBC, SQL Mapper, ORM

사담데이터 파이프라인을 개선하기 위해 JPA에서 JDBC로 변환하면서DB 접근하는 기술에 대해서 맥락과 이해없이 기계적으로만 사용하고 있다는 것을 깨달았다. JDBC는 자바에서 DB를 다루는 근본이기 때문에 이해부터 해야겠다고 판단했다. JDBC배경- 과거에는 애플리케이션에서 DB에 접근하는 방식이 DB마다 달랐다.- DB가 변경되면 애플리케이션 로직도 변경되어야 했다.- 개발자는 DB마다 접근 기술을 학습해야 했다. 등장- 이를 해결하기 위해 JDBC가 등장했다.- JDBC는 자바에서 DB에 접근하는 표준 API이다. 해결- 애플리케이션은 JDBC 추상화에만 의존한다.- 개발자는 JDBC만 배우면 된다.- DB를 변경해도 로직을 수정할 필요없이, 구현 라이브러리만 변경하면 된다. 한계- DB마다 일부 ..

데이터베이스 2024.10.25

DB 저장 배치 처리 - 데이터 파이프라인 개선기

현재 코드는 각 데이터 항목을 저장할 때마다 restaurantRepository.save(restaurant)를 호출하고 있다.50만개 정도의 데이터가 있는데, 그 뜻은 db 통신을 50만 번 해야한다는 소리.. 이래서 시간이 오래걸리고 있었다. 100개씩 받고 saveAll() 로 바꿔도 보았는데,구현체를 보니 단순히 리스트를 돌려 가며 쿼리를 생성하는 것이라 차이점이 없었다.  알아보니 Jdbc로는 배치 처리를 할 수 있다고 해서 이 부분은 jpa를 버리기로 했다. 문제- 현재 50만개 데이터를 처리하고 있는데, 손실되는 데이터가 발생했다.- 8만개 처리하는 시점에 db에 저장된건 5만개이다.- 현재 코드는 각 데이터 항목을 저장할 때마다 restaurantRepository.save(restaur..

카테고리 없음 2024.10.25

JDBC 쿼리 일괄 처리로 DB 통신 횟수를 줄이기

문제데이터 양이 늘어날수록 속도가 느려져, 인텔리제이 프로파일러 기능을 사용해서 스레드를 분석해보았다.가장 오래 걸릴 것이라 예상했던 api 호출작업이 가장 적은 시간이 걸리고, DB 삽입 작업에 어마어마한 시간을 쏟고 있었다. 문제 원인로그를 보니, 데이터 1개마다 DB 쿼리를 생성하고 날리고 있었다.이는 JPA의 saveAll()이 내부적으로는 Iterator를 돌며 save()를 호출하고 있어, 데이터 개별적으로 쿼리가 생성되었다. 해결JDBC는 배치처리를 지원하기 때문에, DB 접근 기술을 JDBC로 변경하였다.100개당 1개의 쿼리를 생성하고 DB 통신을 하게 바꾼 결과,1만 개당 1분에서 2분으로 속도가 개선되었다.

백엔드 2024.10.25

멀티스레드 비동기 구조로 데이터 파이프라인 속도 개선하기

기존 : 데이터 개수별 비동기 처리 기존의 멀티스레드는 데이터 개수를 기준으로 나누었다.데이터를 100개마다 하나의 스레드를 할당해서 수집, 가공, 저장을 하게 했다. 문제1만 개당 30분이라는 긴 시간이 소요되었다. 문제 원인- 멀티스레드 비동기 구조를 의미없이 사용했다.- 하나의 스레드에서 I/O bound 작업과 CPU bound 작업이 섞여있다.- I/O bound 작업이 이루어지고 있을 때는 CPU가 놀면서 자원 낭비를 하게된다.- 앞 작업이 끝날 때까지 다음 작업이 기다려야 하니 결국 스레드 안에서 작업들끼리 blocking이 일어났다.개선 : 작업별 비동기 처리작업별로 스레드를 할당해서, 각 스레드는 맡은 작업만 한다.스레드는 비동기적으로 동시에 이루어진다.수집 스레드가 처리한 결과는 가공 ..

백엔드 2024.10.06

Kakao API 사용자 정보 호출 시 KakaoAccount가 null인 이슈

문제 Kakao API를 통해 사용자 정보를 요청할 때 KakaoAccount가 null로 반환되었다.사용자 ID는 정상적으로 반환되었으므로 API 호출 자체에는 문제가 없는 것으로 보인다.    Postman으로 API 호출 결과 KakaoAccount 정보가 비어 있는 것을 보아, DTO 매핑의 문제는 아니다. 원인Kakao에서 저 정보만 주는 걸로 보아, 애플리케이션 설정이 잘못된 것 같다. 해결콘솔에서 Kakao API의 개인정보 동의 설정을 확인하고 필요한 정보에 대한 동의를 추가하여 문제를 해결했다.  이후 API 호출 시 KakaoAccount 정보가 정상적으로 반환되었다.

백엔드 2024.09.13

GraphQL 커스텀 예외 처리하기

REST API 에서 처리하던대로 RuntimeException만 상속받아 구현한 Exception은GraphQL 에서 예외가 났을 때 잡히지 않았다. 1. GraphQLError를 구현한 Exception 클래스를 만들어준다.package org.example.woodpeckerback.exception;import graphql.ErrorClassification;import graphql.GraphQLError;import graphql.language.SourceLocation;import lombok.Getter;import java.util.List;import java.util.Map;@Getterpublic class GraphQLException extends RuntimeExceptio..

백엔드 2024.09.13

@PostConstruct

Spring은 빈(bean)의 생성 및 소멸에 커스텀 동작을 부착할 수 있게 해줍니다.예를 들어, InitializingBean과 DisposableBean 인터페이스를 구현하여 이러한 동작을 추가할 수 있습니다. Spring은 @PostConstruct로 애너테이션된 메서드를 빈 속성 초기화 직후에 단 한 번 호출합니다.초기화할 것이 없어도 이러한 메서드는 실행된다는 점을 기억해야 합니다.@PostConstruct로 애너테이션된 메서드는 어떤 접근 수준이라도 가질 수 있지만, 정적(static)일 수는 없습니다. @PostConstruct의 한 가지 사용 사례는 데이터베이스를 초기화하는 것입니다.예를 들어, 개발 중에 기본 사용자를 생성하고 싶을 수 있습니다.@Component public class ..

Spring 2024.09.13

로그인 시도 시에도 JWT 필터를 거치는 문제

문제 상황로그인을 성공해야 jwt를 발급받는다.즉, 로그인을 하기 전에는 jwt를 가지고 있지 않는게 당연하다. 그런데 로그인 요청 시에 jwt가 없다는 예외가 터졌다. jwt를 받기 위해 로그인을 하는건데 당연히 없지.. 왜그래?? 원인요청 URL이 로그인 경로라면 JWT 필터를 거치지 않아야 하는데,현재는 이를 고려하지 않고 JWT 필터링을 수행하고 있다. 해결SecurityConfig에서 필터 순서를 수정해주었다. http .addFilterAt(customLoginFilter, UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JwtFilter(jwtUtil), UsernamePasswordAuthenticationFilter...

Spring 2024.09.06