분류 전체보기
Spring Batch Multi-threaded Step 사용 시 chunk 구성에 대한 오해
Spring Batch Multi-threaded Step 사용 시 chunk 구성에 대한 오해
2022.12.16개요 Spring Batch에서는 다양한 병렬 처리 방식을 지원하고 있습니다. AsyncItemProcessor / AsyncItemWriter Multi-threaded Step Parallel Steps Externalizing Batch Process Execution 이 중 Multi-threaded Step 방식에 대해 간단히 설명하고, chunk 구성 관점에서 제가 잘못 이해하고 있었던 부분에 대해 얘기하려 합니다. Multi-threaded Step 방식의 병렬 처리 Multi-threaded Step 방식은 step build 시 `` .taskExecutor()``를 붙여주면, 한 Step 내에서 chunk 단위로 병렬 처리되는 방식입니다. 기존 코드에서 큰 변경 없이 사용이 간단하고 각..
[Spring Batch] 병렬 처리
[Spring Batch] 병렬 처리
2022.09.15Spring Batch에서 지원하는 배치 병렬 처리 방식 AsyncItemProcessor / AsyncItemWriter → 한 step 내에서 processor만 병렬 수행해야 할 때 Multi-threaded Step → 한 step 내에서 reader, processor, writer를 chunk 단위로 병렬 수행해야 할 때 Parallel Steps → 여러 step들을 병렬로 수행해야 할 때 Externalizing Batch Process Execution → 외부 remote 서버에서 병렬 수행 필요할 때. (master-worker 모델) Remote Chunking of Step → 스텝 내의 Processor, Writer가 무거운 작업이라 외부 remote 서버들에서 병렬로 돌리고 ..
[Spring Batch] Scoped Bean 초기화 시 생성자 로깅 누락 문제
[Spring Batch] Scoped Bean 초기화 시 생성자 로깅 누락 문제
2022.07.27이 글은 보호되어 있기 때문에 이것을 보려면 암호가 필요합니다.
[Test] 대역(Test Doubles) : Stubs, Mocks
[Test] 대역(Test Doubles) : Stubs, Mocks
2022.06.10대역의 필요성 테스트를 작성하다 보면 다양한 사유로 대역이 필요해지게 됩니다. 테스트 수행이 외부 의존성에 영향을 주면 안되는 경우 e.g., withdraw 요청이 포함된 기능을 테스트 할 때, 실제로 withdraw 요청이 API 서버에 전달되어서는 안됨. 테스트 내에서 같은 요청을 보냈을 때, 외부 의존성의 응답이 항상 동일할 것이라고 신뢰 할 수 없는 경우 (대부분) e.g., 테스트용 카드를 받았으나, 만료되는 경우 e.g., 외부 의존성에 장애가 발생하는 경우 외부 의존성으로 부터 원하는 응답을 일으키기 어려운 경우 대역의 간단한 예제 테스트 하고자 하는 것이 아래와 같을 때 `` AutoDebitRegister.register(user, cardNum)`` - cardNum 유효성에 따라 V..
[Spring Batch] FileItemWriter
[Spring Batch] FileItemWriter
2022.05.16JsonFileItemWriter java docs code `` [ {json object}, {json object}, {json object} ]`` 형식으로 만들 때. 근데 spring-batch-core 4.1 부터 지원이라... 구버전에는 없다. 구버전에서는? 구버전에서는 FlatFileItemWriter를 쓰거나 직접 ItemWriter 작성해야 하는데 그나마 FlatFileItemWriter가 좀 더 고수준이라 이걸 쓰는게 낫다. (덮어쓰기, 기존 파일 존재하면 삭제 등 설정 가능) 근데 문제는 `` [ {json object}, {json object}, {json object} ]`` 형식으로 만들기가 까다롭다는 점이다. (맨 앞과 뒤에 구분자 , 가 들어간다. JsonFileItemW..
Client IP 구하기 : X-Forwarded-For와 X-Real-IP
Client IP 구하기 : X-Forwarded-For와 X-Real-IP
2022.04.22Proxy / VPN X-Real-IP는 바로 직전 client의 IP를 나타낸다. ``` proxy_set_header X-Real-IP $remote_addr; 설정에서 $remote_addr이, nginx가 수신한 client IP를 의미한다. User - Nginx - Tomcat 일 때, X-Real-IP는 User IP 가 된다. User - Proxy - Nginx - Tomcat 일 때, X-Real-IP는 Proxy IP가 된다. ``` X-Forwarded-For는 3.3.3.3, 1.1.1.1 포맷이다 LB, Proxy, Cache Server 등을 거치면 srcIp가 변경되기 때문에 원래의 Client IP를 가져오기 위한 방법이 필요하다. 이를 위해 X-Forwarded-For 필..
[Spring] EventListener
[Spring] EventListener
2022.04.17https://www.baeldung.com/spring-events ``kt ApplicationEventPublisher::publishEvent``로 pub 하고 ``kt @EventListener``로 event 받아 처리하면 된다. 단 여기서 주의해야 할점! listener가 이벤트를 수신하는 것이 왠지 비동기로 이루어질 것 같지만, 기본적으로 동기식이다! 한 스레드가 pub한 다음, 해당 이벤트를 처리해야 하는 EventListener들을 돌면서 동기식으로 직접 리스너를 수행한다. By default, the listener is invoked synchronously. However, we can easily make it asynchronous by adding an @Async annot..
[Java] 양방향 참조 Enum 초기화 순서에 따른 문제 (순환 참조)
[Java] 양방향 참조 Enum 초기화 순서에 따른 문제 (순환 참조)
2022.04.02취급 대상 품목(Good)은 STONE, ALCOHOL, COMPUTER, SHIP, SUSHI 5가지 이고, 이 중 일부는 목적지(Destination) SEOUL, 일부는 BUSAN으로 보내야 한다. 그리고 목적지에 따라, 해당 목적지로 보내는 품목 리스트를 구할 수 있어야 한다. 그러면 아래와 같이 구현 할 수 있는데... @Getter @RequiredArgsConstructor enum Destination { SEOUL, BUSAN; private static final Map goodsByDestination = Arrays.stream(values()).collect(Collectors.toMap( e -> e, e -> Arrays.stream(Good.values()) .filter(v..
[Spring] MVC Layering Architecture : DTO 전달/변환/파라미터 설계
[Spring] MVC Layering Architecture : DTO 전달/변환/파라미터 설계
2022.03.17Controller -> Service 호출 시, Service의 메서드 파라미터 설계 ```java @PostMapping("/some-path") public ResponseEntity foo(@RequestBody @Valid FooControllerRequest request) { varService.doSomething(request.getGroupId(), request.getUserId()); ... } /* foo API에 변경이 발생했다 */ @DeleteMapping("/some-path/groups/{groupId}/users/{userId}") public ResponseEntity foo(@PathVariable String groupId, @PathVariable String u..
[Spring] MVC Layering Architecture : DTO와 Domain Model을 분리해야 하는 이유
[Spring] MVC Layering Architecture : DTO와 Domain Model을 분리해야 하는 이유
2022.03.14God Class에 대한 용어 정리 god class는, 꼭 크기가 커야만(가지고 있는 필드가 많아야만) god class인 것은 아닙니다. 여러 layer에 걸쳐 사용되고 있다면, 또는 2개 이상의 책임을 가지고 있다면, 그 클래스를 사용(의존)하고 있는 클래스가 그 만큼 많다는 의미이고, 이는 곧 god class (또는 god class 유망주)입니다. god class는 크게 2가지 유형으로 나누어 볼 수 있습니다. (왼쪽) domain 책임은 제대로 나눴으나 여러 layer에 걸쳐 사용되는 경우 = 유형 1 (오른쪽) domain 책임을 제대로 나누지 못해 1개 이상의 책임을 가지는 경우 = 유형 2 유형 1 + 유형 2 = 유형3 이 글에서 주요하게 다루고자 하는 내용은 유형 1 God Cla..
[마틴파울러] Layering 관련 글 모음
[마틴파울러] Layering 관련 글 모음
2022.03.13https://martinfowler.com/bliki/PresentationDomainDataLayering.html layer를 나누는 것의 장점 1. 관심 분리 (를 통해 작업 대상 layer에 집중 가능) 마틴 파울러는 layer를 나누는 것의 최고 장점은, 작업 대상이 되는 layer에만 집중할 수 있도록 해준다는 점이라고 얘기하고 있다. It's biggest advantage (for me) is that it allows me to reduce the scope of my attention by allowing me to think about the three topics relatively independently. When I'm working on domain logic code I ..
[MyBatis] 객체 안의 객체 매핑하기 (ResultMap과 DTO)
[MyBatis] 객체 안의 객체 매핑하기 (ResultMap과 DTO)
2022.03.12객체 안의 객체 매핑하기 https://mybatis.org/mybatis-3/ko/sqlmap-xml.html# - 복잡한 결과매핑 섹션 부터 참조. 읽어 보면 알겠지만, 연관(Association)을 위한 중첩된 Select 는 N+1 Selects problem으로 인해 추천하지 않는다. `` LEFT OUTER JOIN``을 활용한 관계를 위한 내포된 결과(Nested Results) 방법을 사용하는 것을 권장하고 있다 DTO를 사용하면 굳이 객체 안의 객체 매핑 할 필요 없이, DTO에서 flatten해서 받아도 된다. 어차피 쿼리는 `` LEFT OUTER JOIN``을 사용한다면 컬럼을 flatten 해서 가져오게 된다. 따라서 [`` ResultMap - DTO - Model``] 변환의 ..