제 생각과 docs 그리고 다른 분들의 생각 등을 참고하여 작성한 글입니다. 정답이 아닐 수 있으므로 잘못된 부분은 댓글 또는 메일 부탁드립니다!

Transaction을 주의하여 Async 사용하기

이번에 프로젝트 구현하면서 비동기 처리에 대해 필요성을 느끼게 됐습니다. 사용할 때 발생했던 문제점에 대해서 이야기해보려고 합니다. 게시판과 게시글, 댓글의 연관 관계 Board와 Post, Comment를 삭제하는 로직을 예제로 이야기해 보겠습니다. 실제 엔티티들의 데이터 관계 Board를 삭제하면 Post와 Comment도 삭제되어야 하기 때문에 아래와 같은 로직을 작성하게 됐습니다. Board 삭제 시, Post와 Comment 삭제 연쇄 작용 로직 (동기적 처리) 위의 코드를 실행하면, Board를 삭제할 때 Post와 Comment 삭제 시간도 포함하여 대기해야 합니다. 게시판의 데이터가 많다고 가정하면, 응답 시간이 길어지게 되는 상황이 발생하게 됩니다. 당장 Board 하나를 삭제하는 응답이..

Spring 2022.02.20 1

Async를 이용하여 EventListener 사용하기

이전 포스팅에서 트랜잭션을 주의하여 비동기 처리하는 방법에 대해 알아봤습니다. 이번에는 해당 방법을 적용했을 때의 문제점을 고민해봤습니다. 우선, 서비스 로직에 비동기 메서드가 존재하기 때문에 의도하지 않은 다른 곳에서 비동기 메서드를 실수로 사용할 수도 있겠다는 생각을 하게 됐습니다. 비동기 처리에는 앞선 포스팅에서 설명드린 것처럼 트랜잭션 문제를 야기할 수 있기 때문에 실수로 사용하지 않기 위해서 똑같은 메서드를 구현해주어야 하는 불편함도 있습니다. 그래서, 여러 메서드에 각각 비동기 처리를 해주는 대신, 하나의 메서드에서 비동기로 처리할 각 함수를 호출하고 이를 비동기 처리하면 좋겠다는 생각을 했습니다. 또한, 게시판을 삭제하기 위해서 게시글과 댓글, 좋아요 등을 삭제하는 추가적인 로직을 수행해야 ..

Spring 2022.03.16 2

로컬 환경에서 Redis Cluster 구성하기

서론API 서버에서 데이터를 더 빠르게 읽을 수 있도록 Batch 서버에서 캐시를 적재하는데, 해당 로직에 새로운 기능을 추가하는 업무를 맡게 되었습니다. 이 과정에서 애플리케이션의 로컬 환경에서 캐시 데이터를 즉각적으로 적재, 수정, 삭제하며 개발을 진행하기 위해 Redis 로컬 환경을 구성하고 연동하는 것이 필요하다고 판단했습니다.특히, Batch 서버에서 사용되는 Redis가 클러스터 구조로 되어 있어 이를 로컬 환경에서 재현하고 테스트하는 데 어려움이 있었습니다. 이러한 문제를 해결하면서, 로컬 환경에서 Redis 클러스터를 설정하고 이를 서버에 연동하는 방법을 공유하고자 합니다.본론 1: Redis Cluster 구조Redis Standalone 구조기본적으로 Redis를 설치하고 실행하면 st..

Redis 2024.06.13 10

Facade Layer 도입하게 된 이유

이번에 게시물 서비스를 구현하면서 두 번의 시행착오를 겪고 퍼사드 레이어를 도입하게 됐습니다. 어떤 이유인지 예제 코드로 문제점을 확인하여 설명하겠습니다. 회원과 게시판, 게시글의 연관 관계 위처럼 Post를 생성할 때는 Member의 정보와 Board의 정보가 필요합니다. 이것을 고려하여 Post를 생성해 보겠습니다. Repository를 주입하여 Post 생성하기 PostService에서 다른 도메인의 레포지토리를 주입하여 구현했습니다. 이것은 PostService의 역할과 책임을 적절하게 나누지 못한 케이스입니다. 결국에 위의 코드처럼 레포지토리를 주입하는 곳마다 똑같은 로직을 구현해야 하는 문제가 발생하게 됩니다. 그래서 각 도메인의 레포지토리는 각 서비스에서 구현해야 합니다. 그렇다면, Post..

Spring 2022.02.16 3

Spring batch BadSqlGrammarException

Description 스프링 배치를 처음 실행하려고 하면 BadSqlGrammarException 에러가 발생하는 현상이 있습니다. Error message java.lang.IllegalStateException: Failed to execute ApplicationRunner ... ... ... Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; nested exception is java.sql.SQ..

Spring 2022.06.21 0

Slack으로 에러 알림 받기

현재 제가 담당하고 있는 팀 프로젝트에서 발생하는 에러를 효과적으로 처리하고, 팀원들이 이를 실시간으로 확인할 수 있도록 개선하고자 합니다. 간단하게 Slack webhook API를 활용하여 이를 해결해보려고 합니다. Slack webhook URL 생성하기 구현하기 전에 이미 slack workspace가 있다고 가정하고 설명하도록 하겠습니다. slack webhook을 생성하기 위해서는 아래와 같이 https://api.slack.com/apps 페이지에 접속해야 합니다. webhook를 생성하기 위해서는 app을 생성해야 합니다. “Create New App”를 클릭합니다. “From scratch”를 클릭합니다. 그리고 생성할 “App Name”을 적어줍니다. 이는 알람을 보내는 주체가 됩니다...

Spring 2023.06.01 4

Spring batch란

해당 글은 이론 위주의 설명입니다. 실제로 구현한 예제는 여기에서 볼 수 있습니다. 이번에 배치 모듈을 사용해보게 됐습니다. 한 번도 배치 모듈을 사용해본 적이 없었지만, 앞으로 배치를 자주 사용하게 될 것 같아 공부하면서 내용을 정리해보려 합니다. 왜 사용할까? 크롤러로 어떤 사이트의 정보를 주기적으로 긁어 온다고 가정해보겠습니다. 크롤링할 때마다 개발자가 직접 API로 수행해야 할까요? 아닙니다. 자동으로 할 수 있다면 좋을 것입니다. 또한, 크롤링하는 정보의 양이 상당히 많다면 서버의 자원을 다 써버려서 다른 작업을 수행하기에 어려운 상태가 됩니다. 그렇다면, 사용량이 적은 시간대인 새벽에 처리한다면 좋을 것입니다. 그리고, 1억 개를 처리한다고 할 때 5만 번째에서 실패를 했는데 자동으로 5만 1..

Spring 2022.06.30 0

java.lang.UnsupportedOperationException

서론 java.lang.UnsupportedOperationException은 특정 연산이나 기능이 현재의 상황에서 지원되지 않을 때 발생하는 예외입니다. 이 예외는 주로 불변 객체나 수정이 불가능한 상태의 컬렉션에서 발생하며, 이에 대한 적절한 처리가 필요합니다. 이 예외가 발생하는 두 가지 예제를 통해 어떻게 해결할 수 있는지에 대해 설명하겠습니다. Arrays.asList()로 생성된 고정 크기 리스트에 원소 추가 Collections.singletonList()로 생성된 리스트에 원소 추가 결론 이처럼 불변 컬렉션으로 선언된 객체에 대해서 가변 하게 사용하면, java.lang.UnsupportedOperationException가 발생할 수 있습니다. 아래 코드는 올바른 예제입니다. 이상입니다...

Java 2023.12.28 0

Linux Terminal Backspace Issue

Description 리눅스 터미널에서 Backspace 키가 공백이나 제어 문자 (^H 또는 ^?)로 인식되는 경우에 해결 방법을 제시하겠습니다. Solution export TERM=vt100 Conclusion 이런 경우는 일반적으로 터미널 설정과 관련이 있습니다. 터미널은 환경 변수인 TERM을 사용하여 터미널의 유형을 식별합니다. TERM 변수는 터미널이 어떤 기능과 동작을 지원하는지에 대한 정보를 제공합니다. "export TERM=vt100" 명령은 TERM 환경 변수를 "vt100"으로 설정하는 것을 의미합니다. vt100은 오래된 터미널 유형 중 하나로, 대부분의 터미널에서 동작하는 터미널 에뮬레이터입니다. vt100으로 설정하면 백스페이스 키를 올바르게 인식할 수 있습니다. Refere..

Etc 2023.05.31 0

통합 테스트와 단위 테스트

글에서 나오는 예제의 구현 코드와 테스트 코드는 해당 링크에 있습니다. 이번에 팀 내에서 테스트 코드를 어떤 방법으로 작성하면 좋을지 고민하던 중, TDD와 BDD에 대해 다시 공부하게 됐습니다. TDD와 BDD 외에도 DDD, ATDD 등 수많은 xDD가 존재합니다. xDD는 모두 소프트웨어 개발 방법론입니다. x주도 개발이라고 해서, 어느 것을 중점으로 두고 개발을 진행할지 미리 정해 두는 것입니다. 저는 그중에서도 TDD와 BDD 그리고 테스트 코드에 대해 고민해 봤습니다. TDD 사진 출처 TDD는 테스트 주도 개발이라는 뜻입니다. 요구사항이 주어지면, 요구사항에 대한 에러를 고민하고 바로 에러에 대한 테스트 코드를 작성한 후, 해당 테스트를 통과하도록 구현 코드를 작성하는 개발 방법론입니다. 예..

Spring 2022.07.28 0

슬라이스 테스트를 하게 된 이유

테스트하는 이유 개발자라면 때때로 기능을 구현하고 나서 실행을 했을 때, 에러가 발생할 때가 있을 겁니다. 에러를 잡는데 짧은 시간이 걸릴 때도 있지만, 오랜 시간이 걸리기도 합니다. 특히, 저 같은 초급 개발자라면 경험이 부족하기 때문에 더욱 오래 걸릴 거라고 생각합니다. 에러를 잡는데 오랜 시간이 걸린 적이 많았고, 정말 사소하고 간단한 부분을 잘못해서 발생한 문제를 오랜 시간 동안 고민하여 해결한 적도 있습니다. 테스트 코드를 짜는 이유는 많지만, 저는 이러한 점을 해결하기 위해서 테스트 코드가 꼭 필요하다고 생각했습니다. 본인이 새롭게 작성한 코드마다 테스트를 진행하게 된다면, 적어도 기능이 완성됐을 때의 에러가 나의 코드로 인한 문제가 아닌 설정 등과 같은 외부 요인에서 발생한 문제라는 것을 알..

Spring 2022.03.18 0

Immutable object, 불변객체

불변 객체란? 불변 객체란 재할당은 가능하지만, 이미 할당된 내부 데이터를 변경시킬 수 없는 것을 말합니다. 쉽게 말해서, 한 번 만들면 수정이 불가하고 수정하고 싶다면 다시 만들어야 합니다. 불변 객체의 예시 Java의 불변 객체의 대표적인 예로는 String이 있습니다. String.class를 둘러보면, 원시 타입의 필드 값인 value는 전부 생성자를 통해서 관리하고, 나머지 메서드는 Read Only만 가능합니다. 이 말이 뜻하는 것은 String은 한 번 할당하면 내부 데이터를 변경할 수 없고, 변경하고 싶다면 생성자를 통해서 재할당해야 한다는 것입니다. 즉, 불변 객체라는 말입니다. 평소에 String 값을 바꿀 때 변경하는 것처럼 보이지만, 사실은 아래처럼 변경하는 것이 아니라 재할당 해주..

Java 2022.04.17 0

Fixture monkey

Fixture 테스트를 수행하는 데 필요한 정보나 오브젝트를 말한다. Fixture monkey 테스트 수행에 필요한 픽스쳐를 간편하게 바인딩해주고 랜덤한 값을 넣어줄 수 있도록 하는 라이브러리입니다. given 단계가 길어지면서 코드의 가독성을 떨어뜨린다고 느껴져서 이를 도입하게 되었습니다. 예제를 통해서 이를 적용해 보겠습니다. 리팩토링 전 리팩토링 후 이처럼 픽스쳐 몽키를 사용합니다. 픽스쳐 몽키를 사용하면서 여러 가지 장점을 느꼈는데, 개인적으로 제가 좋다고 느낀 것을 말씀드리겠습니다. 랜덤한 값 바인딩 픽스쳐 몽키는 랜덤한 값을 바인딩해주며, 랜덤 설정 또한 어떻게 랜덤하게 할 건지 정의해줄 수 있습니다. 랜덤 값의 바인딩 기능은 테스트를 실행할 때마다 새로운 값들이 바인딩됨으로써 코드의 신뢰성..

Spring 2022.03.18 0

@WebMvcTest에서 Security config class 제외시키기

Description Junit 5 환경에서 스프링 슬라이스 테스트를 위해서 컨트롤러 테스트를 진행하던 중 JWT 토큰 관련해서 에러가 발생했습니다. 테스트하려고 하는 URL이 시큐리티에서 허락을 안해주고 있기 때문에 인증을 받아야 테스트를 할 수 있습니다. 독립적인 테스트를 하는게 중요한 것이기 때문에 시큐리티까지 해줄 필요는 없다고 생각했습니다. 그래서, @WebMvcTest에 대한 Spring Security config 클래스를 비활성화시켜주어서 해결했습니다. Error message *************************** APPLICATION FAILED TO START *************************** Description: Parameter 0 of construc..

Spring 2022.03.10 0