- 개요 - 스프링 프로젝트에서 서킷브레이커를 적용하기 위해서는 아래의 2가지 프레임워크를 이용합니다 hystrix circuit breaker resilience4j circuit breaker 현재는 hystrix circuit breaker는 2021년 11월 1일부로 공식적인 지원이 중단되어 사용을 추천하지 않습니다. 😭 따라서 이번 글에서는 resilience4j 의 circuit breaker을 설명하도록 하겠습니다. 우선 의존성은 아래와 같습니다. dependencies { implementation 'io.github.resilience4j:resilience4j-spring-boot2:{version}' } 스프링 부트 버전과 호환되는 각각의 resilience4j 은 아래와 같으니 현재..
기본개념 배치 계층 구조에서 가장 상위에 있는 개념(하나의 배치작업 자체이다) 적어도 하나 이상의 step을 포함하고 있는 컨테이너 기본 구현체 SimpleJob 순차적으로 Step을 실행시키는 Job 모든 Job에서 유용하게 사용할 수 있는 표준 기능을 갖고 있음 FlowJob 특정한 조건과 흐름에 따라 Step을 구성하여 실행시키는 Job Flow 객체를 실행시켜서 작업을 진행함 Job 은 어떻게 만들어지고 어떻게 실행되는 걸까?? 대부분 JobBuilderFactory 을 이용하여 Job 생성하게 된다. jobBuilderFactory.get("simpleJob") // job 의 이름을 정한다. .start(simpleStep1()) // 실행할 step 을 지정한다. .next(simpleSte..
해당 질문에 대해서는 서비스가 어떻게 구축되었는가에 따라 정답이 다르겠지만 적어도 yml에서 관리되고 있는 property 가 동일한 값을 여러 프로젝트에서 사용하고 있다면 매우 필요하다고 느끼고 있다. 왜 필요한가? 예를 들어 여러 프로젝트에서 Slack 알림을 발송하고 있다고 가정해보자. Slack 알람을 발송하기 위해선 webHook 이 필요할 것이다. 또한 채널명도 알고 있어야 된다. 간단하게 아래와 같은 그림이 될 것 같다. 만약 현재 상태에서 슬랙 채널의 이름이 변경된다고 가정해보자. 그러면 모든 프로젝트의 yml 파일에 가서 정보를 변경해야 한다 여기까지는 충분히 할 수 있다. (만약 프로젝트가 많다면 해당 슬랙 채널로 발송하고 있는 프로젝트를 다 찾아야 한다.) 하지만 코드를 변경했지만 S..
서론 이번 글에서는 findById(), getById() 메서드의 차이점과 제가 생각하는 느낀 점에 대해 말해보고자 합니다. 따라서 개인적인 생각이 담긴 글이니 어느정도 비판적인 시각으로 봐주시면 감사하겠습니다. 사전 설명 다음과 같은 Entity 연관관계를 가지고 있을 때 저희는 일반적으로 게시판에 해당하는 댓글을 추가하기 위해서클라이언트 요청으로부터 게시판의 Id, 댓글내용, 작성자 등 필요한 정보를 받게됩니다. 그러면 저희는 Serivce Layer에서 해당하는 게시판이 있는지 확인 후 Reply 객체를 생성해서 연관관계를 맺은 후 저장하게 됩니다. 간단히 이러한 로직이 만들어지게 됩니다. public void save(RequestReply requestReply) { // 해당하는 게시판이 존..
서론 데이터베이스를 이용한다면 대부분 쓰기보다 읽기 의 행위가 더 많습니다. DB의 부하를 줄이기 위해 다음과 같이 Master - Slave 구조를 많이 사용하는데요. 이러한 구조를 가지고 있을 때 Transection의 속성이 readOnly = true 인 경우 Slave 데이터베이스에 Select query 가 발생하게 해야합니다. 따라서 이번 본문에서는 @Transactional(readOnly = true) 인 경우는 Slave DB 접근 @Transactional(readOnly = false) 인 경우에는 Master DB 접근 위의 조건을 만족하기 위한 방법을 Spring-boot 기준으로 소개하고자 합니다. 사전 환경설정 실습 환경은 다른 것은 필요 없고 저는 MySQL 데이터베이스를 ..
서론 스프링 컨트롤러에서 클라이언트로부터 받은 값을 검증하기 위해 Validation을 많이 사용하곤 합니다. JSR 380이 제공해주는 Bean Validation 의 종류는 다양하지만 각자의 서비스에 따라 기본적으로 제공해주는 애노테이션만으로는 검증을 모두 다 지원해주지는 못합니다. 따라서 상황에 따라 각 서비스에 맞는 커스텀한 Validation을 만들어서 활용하기도 합니다. 그렇다면 이번 글에서는 왜 커스텀 Validation을 만들었고 만드는 과정을 소개하고자 합니다. 왜 필요한가? 기존 @NotNull, @NotEmpty, @NotBlank, @Email 등의 애노테이션으로 클라이언트 요청으로 값을 검증하는 것은 필드 자체의 형식이나 값을 체크하는 용도로만 사용됩니다. 즉 필드와 필드를 비교하..
이번글에서 소개하고자 하는 것은? 이번 글에서는 컨트롤러에서 @AuthenticationPrincipal 을 사용하여 Principal 객체를 바인딩 받아 사용하는 경우를 테스트 코드를 작성하기위한 글입니다. (테스트를 작성하는 방법은 여러가지 있음으로 해당 글이 무조건 옳은 방법의 테스트라고 주장하는 글이 아닙니다.) 서론 컨트롤러 예제는 다음과 같습니다. @GetMapping("/hi") public ResponseEntity hi(@AuthenticationPrincipal AuthUser user) { return ResponseEntity.ok("Hi !" +user.getEmail()); } 해당 컨트롤러를 테스트하기위해서는 AuthUser가 SercurityContextHolder 에 담겨 ..
JPA를 사용하게 되면 트랜잭션 격리 수준이 READ COMMITTED 정도가 된다. 격리 수준 READ UNCOMMITTED (거의 안 써요!) 커밋되지 않은 데이터를 읽을 수 있음 -> Dirty Read , Dirty Write 발생 가능 READ COMMITTED 커밋된 데이터만 읽기 -> Read Skew 발생 가능 REPEATABLE READ 트랜잭션 동안 같은 데이터를 읽게 함 -> Lost Update 발생 가능 SERIALIZABLE 모든 트랜잭션을 순서대로 실행 (실제로는 인덱스 잠금이나 조건 기반 잠금을 사용) 트랜잭션 격리 수준이 높아질수록 오버헤드가 커짐으로 잘 선택하여 사용해야 합니다. JPA를 사용하면서 READ COMMITTED 이상의 격리 수준이 필요할 때 비관적 락 , 낙..