개발
-
MySQL Binlog CDC 구현(2) - Binlog 변환개발 2024. 12. 26. 06:14
지난 포스팅에 이어 Binlog 를 파싱하여 이벤트를 발행하는 과정입니다. Binlog는 크게 다음과 같은 정보를 가지고 있습니다.- 어떠한 EventType의 Binlog 인지- 몇번째 컬럼의 데이터인지를 나타내는 Bitset- 데이터 정보 등등 컬럼명에 대한 정보가 없으니 원본 데이터로 파싱하기란 불가능합니다.따라서 MySQL의 Metadata를 통해 컬럼의 인덱스와 컬럼명을 알고 있어야 적절히 컬럼명과 데이터를 매핑할 수 있습니다.초기화 @PostConstruct public void init() throws SQLException { try (Connection connection = jdbcTemplate.getDataSource().getConnection()) { Resul..
-
MySQL Binlog CDC 구현(1) - Binlog 읽기개발 2024. 12. 5. 04:28
Binlog란?Binlog는 Binary Log라고도 불리며, 데이터베이스에서 발생하는 변경 사항(예: 테이블 생성, 데이터 변경 등)을 기록한 이벤트(Event)를 포함하는 로그 파일입니다.아래는 MySQL 공식 문서에서 발췌한 설명입니다:The binary log contains “events” that describe database changes such as table creation operations or changes to table data.(출처: MySQL 8.4 Reference Manual)이처럼, Binlog는 데이터베이스의 변경 작업을 이벤트로 기록하며, 데이터 복구와 복제(Replication)와 같은 중요한 작업에서 핵심적인 역할을 합니다.Binlog를 활용한 CDC 구현저..
-
AOP를 활용하여 로깅 기능 개발개발 2024. 11. 13. 00:03
개발을 진행하다 보면 디버깅을 통해 에러를 찾고 해결하는 일이 많습니다. 하지만 운영 환경, 즉 배포된 서버에서는 개발 환경처럼 쉽게 디버깅하기 어렵습니다. 이때 중요한 것이 로그입니다. 로그는 문제의 원인을 빠르게 파악하고 해결하는 데 도움이 됩니다.현재 프로젝트에서는 커스텀 에러를 발생시키고, ControllerAdvice에서 이를 일괄적으로 처리하고 있습니다. 그러나 요청별로 어떤 정보를 담고 있는지까지 파악하기 위해서는 추가적인 정보가 필요합니다. 특히 다음 정보들을 로그에 포함하면 에러 처리 뿐만 아니라 사용자의 요청을 분석하여 캐시할 데이터를 선정하는 데 도움이 될 수 있다고 판단하여 로그에 남기기로 했습니다.HTTP 요청 정보사용자 정보위 정보들은 모든 요청에 대해 적용되어야 하며, 이를 A..
-
findAll vs Stream vs Batch처리 비교개발 2024. 11. 7. 17:41
프로젝트에서 특정 경로에 대한 이벤트 발생 시 해당 경로를 일정 시간 내에 지나갔거나 근처에 있었던 모든 유저들에게 알림을 발송해야 합니다. 만약 알림을 보내야 하는 회원이 적다면 findAll()을 통해 전체 회원을 조회하여 처리해도 문제가 없겠지만, 서비스가 확장되어 알림 대상 회원 수가 급증할 경우에는 성능 및 메모리 사용 문제가 발생할 수 있습니다. 이에 따라, 데이터 양이 증가할 때 발생할 수 있는 문제를 분석하고, 여러 방식으로 성능 테스트를 진행해 보았습니다.이번 테스트는 초기 1만 건의 데이터를 기준으로 시작하여, 힙 사이즈 512MB를 초과할 때까지 데이터 수를 2배씩 증가시키며 진행했습니다. 테스트 방식은 다음과 같습니다.전체 회원 조회 후 한 건씩 알림 발송:전체 데이터를 메모리에 한..
-
JPA N+1 감지 기능 구현기개발 2024. 10. 30. 23:14
N + 1 문제는 JPA를 사용할 때 자주 겪는 성능 문제로, 연관된 엔티티들을 반복적으로 조회하면서 추가적인 쿼리가 발생하는 현상입니다. 이러한 N + 1 문제는 쿼리 수 증가와 메모리 점유율을 높여 성능 저하를 유발할 수 있습니다. 프로젝트를 진행하며 N + 1 개념을 모르고, 해결법을 몰라서가 아닌 개발자의 실수로 N + 1 문제가 발생하는 상황을 종종 볼 수 있었습니다. 개발 환경에서 발생되는 쿼리를 보고도 충분히 문제를 방지할 수 있지만 N + 1 문제가 발생하면 로깅을 통해 문제상황을 감지, 개발생산성을 높이고자 하여 기능 개발을 하게 되었습니다.접근 방식우선, 로깅을 남기기 위해 N+1 문제의 명확한 정의가 필요했습니다. 다음과 같이 정의를 내렸습니다.즉시 로딩(FetchType.EAGER..
-
JOOQ 테스트 환경 분리하기개발 2024. 9. 25. 16:07
jooq는 DSL을 사용하여 자바 코드를 쿼리로 변환하여 데이터베이스 작업을 한다.여기서 사용되는 DSL 코드는 실제 데이터베이스의 테이블 정보를 컴파일 시점에 읽고 생성하여 런타임 시에 사용되는 구조이다.프로젝트를 진행하며 테스트 환경 분리가 필요했다.기존의 테스트는 데이터베이스를 사용하는 테스트를 진행하기 위해서는 실제 데이터베이스를 실행해야하는 수고스러움이 있었다. 만약 데이터베이스를 실행하지 않고 테스트를 실행하면 DSL 코드를 생성할 테이블 정보를 읽지 못해 에러가 발생한다. 이를 해결하고자 testContainer 를 도입하여 테스트 환경에서 컨테이너를 띄워 테스트의 환경을 격리 시키기로 했다.문제점jooq 는 위 설명처럼 빌드 시 데이터베이스에 접근해 메타데이터를 기반으로 DSL 코드를 생성..
-
메인 기능, 부가 기능 분리 그리고 Transactional outbox pattern개발 2024. 9. 4. 17:16
도서 공유 프로젝트를 진행하며 겪은 문제들과 이를 해결해나가는 과정을 담은 글입니다.도서의 상태가 변경되면 해당 도서를 팔로우 하고 있던 사용자들에게 알림을 보내는 기능이 있다.도서의 상태를 변경하는 메인 기능.도서를 팔로우 하던 사용자들에게 알림을 주는 부가 기능.하나의 클래스에서 처리하던 기능을 두 가지의 기능으로 분리하고자 했다. 분리를 하는 이유메인 기능과 부가 기능이 같이 있어 코드의 의도를 파악하기에 어렵다.부가 기능의 변경으로 메인 기능이 변경되어야 할 상황이 발생할 수 있다.하나의 클래스는 하나의 책임만을 지는 것이 원칙이다. 로버트 마틴은 하나의 클래스는 하나의 액터만을 책임져야 하며, 이를 단일 책임 원칙이라고 한다.현재의 기능은 도서의 소유자, 도서를 팔로우하고 있는 사용자. 즉 액터..
-
테스트하기 안 좋은 코드 리팩토링하기개발 2024. 8. 20. 21:04
삼성청년SW아카데미 11기에서 진행한 도서 공유 프로젝트가 마무리 되었습니다. 프로젝트가 마무리 되었으니 문제점이라고 생각한 부분을 리팩토링을 하였습니다. 리팩토링의 목표는 테스트 하기 좋지 않은 코드를 테스트하기 좋은 코드로 바꾸는 것이었습니다. 💡 테스트하기 좋지 않은 코드란?테스트 코드는 항상 같은 결과를 return 하는 멱등성이 보장되어야 합니다.만약 Rental을 생성하는 테스트 코드를 작성했는데, 이 코드에 멱등성이 보장되지 않은 코드가 있고,이 코드로 인해 어떤 경우에는 테스트가 성공하고, 어떤 경우에는 테스트가 실패한다면 이는 테스트로서의 기능을 못하고 있는 것입니다.따라서 멱등성을 보장하지 못하는 코드는 테스트 비용을 지불하여 멱등성을 보장해주어야 합니다.이때의 방법은 Mocking,..