백엔드 9

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

활용성있는 데이터 파이프라인 구축을 위한 아이디어

아이디어 1️⃣원본 테이블과 운영테이블(데이터 가공 테이블)로 분리하여 관리하기 도입 이유- 전처리 방식을 유연하게 변경할 수 있다. - 데이터 가공 시 오류가 발생해도 원본 데이터를 보존할 수 있다.  과정데이터 읽어오기 (API 데이터 호출 → 원본 테이블에 저장)데이터 가공하기 (원본 테이블 → 가공한 데이터를 운영 테이블에 저장)아이디어 2️⃣데이터 업데이트시, 해시값을 저장해서 데이터 변경 감지 도입 이유- 오직 변경만을 감지하기 위해 데이터를 파싱하여 저장할 필요가 없다.- 운영테이블에는 변경이 감지된 데이터만 저장하면 된다.- 업데이트 된 값만 변경하고 저장하여 속도를 개선할 수 있다.과정원본 테이블에는 원본 데이터(json), 해시, 변경 플래그 컬럼이 존재한다.해시만을 비교하여 달라진 레..

백엔드 2024.08.30

할인 정책 개발 - 추상 클래스와 인터페이스 중에 어떤걸 사용할까?

장바구니와 주문 기능에 이어, 할인 정책 기능을 추가하기로 했다.  할인 방식에는 대표적으로 정액 할인과 정률 할인이 있다.이를 위해 할인을 추상화하고, 정액 할인과 정률 할인을 구체적으로 구현하고자 했다. 그런데 할인을 abstract class로 정의할지, interface로 정의할지 고민이 되었다.둘 다 추상 메소드를 통해 다형성을 제공한다는 점 때문이었다.둘의 역할이 정확히 어떻게 되는걸까? 추상 클래스는 멤버 변수와 메소드를 가질 수 있으며, 상속을 통하여 사용할 수 있다.공통적인 기능을 갖지만 특정 기능은 구현 클래스에서 달라질 수 있다. 예를 들어, 동물을 객체로 구현할 때 추상 클래스를 사용할 수 있다.동물 추상 클래스에는 먹기, 자지와 같은 공통적 행동을 정의할 수 있다.그리고 동물 추상..

백엔드 2024.08.14

모델링 - 다대다 관계 설계하기

이커머스를 만들것이다.5일 안에 기능 동작은 물론, 테스트 코드까지 작성을 해야하므로 일단 기능 요구사항은 최소화하기로 했다. 최소 기능 요구사항은 장바구니와 주문이다. 개체는 사용자, 상품, 장바구니, 주문이 된다는 것은 알겠다.하지만 서로의 관계를 한 번에 정의하려니 복잡하다. 장바구니에는 여러 개의 상품이 담길 수 있다.그럼 여러 개의 상품 컬럼이 있어야 하는건가?몇 개의 상품이 담길지 알 수 없으니 미리 정의하는 것은 불가능하다. 장바구니 개체가 상품을 참조하지 않고상품이 장바구니를 참조하는 것은 어떤가?장바구니가 생성되면 장바구니에 담긴 상품이 장바구니 번호를 참조하는 것이다. 그렇게 되면 장바구니 개체는 명확히 정의할 수 있지만상품 개체의 똑같은 문제가 발생한다.이 상품이 몇 개의 장바구니에 ..

백엔드 2024.08.06

JWT 이해하기

JWT(JSON Web Token)- 인증에 필요한 정보를 토큰에 담습니다.- 데이터가 Json의 형식으로 담깁니다.- 주로 클라이언트와 서버 간에 인증 정보를 교환할 때 사용합니다. 구성1. Header : 토큰 타입 + 사용할 해싱 알고리즘2. Payload : 사용자의 정보3. Signature : 비밀키를 사용해 생성된 서명 무슨 말인지 잘 모르겠습니다..영화관 입장권로 비유하여 이해해보겠습니다. 영화관에 들어가려면 입장권이 필요합니다.입장권은 해당 영화관에서만 발급할 수 있습니다.진짜 입장권인지 식별하기 위해, 입장권에는 영화관 도장이 찍혀있습니다.입장권에는 무슨 영화를 보는지, 몇 시에 입장하는지, 좌석 번호가 무엇인지와 같은 정보가 적혀 있습니다. JWT도 이와 같습니다.1. 페이로드 = ..

백엔드 2024.03.10

PUT vs PATCH

아무 생각없이 수정 api에서 put 메소드를 쓰다가프론트 팀원이 일부 리소스만 수정하는데, patch를 써서 명확히 하는게 좋겠다는 의견을 주셨다. 정리메소드PUTPATCH설명- 전체 정보 수정하기- 테이블 레코드 한 줄을 다 바꾼다고 생각- 일부 정보 수정하기- 패치 붙이는 것처럼 특정 부분 수정하기- 테이블 레코드 해당 줄에 특정 부분에 패치 붙여서 수정한다고 생각예시- 사용자 정보 변경하기- 좋아요, 공유 수 올리기- 비밀번호 변경하기

백엔드 2024.02.25