목록분류 전체보기 (153)
늘
정확히는 MySQL에서 PagingQueryProvider와 JdbcPagingItemReader을 함께 사용할때 페이징은 offset을 사용하지 않는다 입니다. 문제 상황으로는 JdbcPagingItemReader를 통해 조회를 할때, SELECT 절에 별칭을 주었는데 정상적으로 읽지 못하는 문제가 발생했습니다. 해당 이슈를 해결하면서 알게된 사실을 공유하려고 합니다. (직접 코드를 기반으로 추정한 것이기에 다른 의견이 있으시다면 댓글을 남겨주세요) JdbcPagingItemReader @Bean @StepScope public JdbcPagingItemReader reader() { return new JdbcPagingItemReaderBuilder() .name("reader") .pageSize..
spring batch 5는 이전 버전과 많이 변경되었다. 기본적인 스프링배치부터 스프링 배치 5.0은 어떻게 달라졌는지 직접 실무에 적용해보면서 느꼈던 경험을 적어본다. Architecture 공식문서에 나온 아키텍처이다. Application, Core, and Infrastructure 로 구성되어있다. Application: 애플리케이션에는 Spring Batch를 사용하여 개발자가 작성한 모든 배치 작업과 사용자 정의 코드가 포함되어 있다. Batch Core: 배치 작업을 시작하고 제어하는 데 필요한 핵심 런타임 클래스가 포함되어 있습니다. JobLauncher, Job, and Step이 포함되어있다. Batch Infrastructure: 애플리케이션과 코어는 모두 공통 인프라 위에 구축..
스터디를 하면서 실무에 적용하기 좋은 챕터라고 생각되어 따로 정리해둡니다. 유연하고 재사용 가능한 퍼블릭 인터페이스를 만들기 위한 원칙과 기법을 살펴보는 것이 주제이다. 우선 협력과 메시지에 대해 알아보자. 협력 관계를 설명하는 전통적인 메타포는 클라이언트-서버 모델이다. 협력은 클라이언트가 서버의 서비스를 요청하는 단방향 상호작용이다. 그리고 객체는 클라이언트와 서버의 역할을 동시에 수행한다. 협력의 관점에서 객체는 두 가지 종류의 메시지 집합으로 구성된다. 하나는 객체가 수신하는 메시지의 집합이고 다른 하나는 외부의 객체에게 전송하는 메시지의 집합이다. 협력에 적합한 객체를 설계하기 위해서는 외부에 전 송하는 메시지의 집합도 함께 고려하는 것이 바람직하다. 용어정리 메시지는 객체들이 협력하기 위해 사..
RPC 원격 프로시저 호출(Remote Procedure Call)은 네트워크의 세부 사항을 이해하지 않고도 한 프로그램이 네트워크의 다른 컴퓨터에 있는 프로그램에 서비스를 요청하는 데 사용할 수 있는 소프트웨어 통신 프로토콜이다. RPC는 클라이언트 - 서버 모델이다. 요청하는 프로그램은 클라이언트이고, 서비스를 제공하는 프로그램은 서버이다. 로컬 프로시저 호출과 마찬가지로 RPC는 원격 프로시저의 결과가 반환될 때까지 요청 프로그램을 일시 중지해야 하는 동기 작업이다. 그러나 동일한 주소 공간을 공유하는 경량 프로세스 또는 스레드를 사용하면 여러 RPC를 동시에 수행할 수 있다.(+ grpc를 사용하면 비동기식으로 사용할 수 있다.) API를 설명하는 데 사용되는 사양 언어인 IDL(인터페이스 정의 ..
본 게시글은 지속적으로 학습하면서 업데이트할 예정입니다. 동작원리 컨테이너 빌드(nginx, payment, batch …) 사용자가 docker push hub.example.com/nginx 와 같이 docker hub에 저장해둔다.(사내, docker.com 등) 이후, 쿠버네티스 명령어를 통해 저장해둔 컨테이너가 실행하도록 한다.(yaml or kubectl 명령어로 실행 가능) 명령어를 실행하면, 마스터 노드(Control-plane)에 요청이 간다. 마스터 노드는 API서버가 있어서 쿠버네티스관련 요청을 받는다. 스케줄러에게 어떤 워커 노드에 nginx를 실행하면 좋을지 물어보면, 스케줄러가 워커 노드의 상태를 보고 적절한 노드를 응답해준다.(REST API서버에게) API서버는 할당받은 워커..
일반적으로 분산 시스템에서 메시지를 주고받는 방법으로는 크게 2가지가 있다. API를 통한 통신 즉각적인 요청과 응답을 주고받는다. 간단한 개발 메시지 큐를 통한 통신 비동기, 배치 처리와 함께 적용하기 좋다. 일반적으로 publisher가 데이터를 큐에 넣으면 consumer가 큐에서 데이터를 꺼내서 데이터를 가공한다. 복잡한 개발 분산 시스템에서는 모든 데이터가 네트워크를 타면서 이동하므로 지연, 유실 등의 문제가 발생할 수 있다. 따라서 아래의 3가지 방식을 통해 데이터 전달을 보장하는 방법이 있다. 1. At most once producer가 최대 한 번만 송신하고 consumer가 최대 한 번만 수신한다. 간단한 구현 & 개발이지만 데이터 유실 가능성이 높다. 대용량 메세지 전송할 때 편하다...
톰캣은 was로서 내부에 웹 서버와 웹 컨테이너(서블릿 컨테이너)로 이루어져 있다. 예전에는 정적인 페이지만 줬었기 때문에 웹서버만 있으면 됐다. 하지만 동적인 페이지를 요구하기 시작했고 CGI(Common gateway Interface)가 나왔다. 하지만 CGI는 요청마다 프로세스를 생성해서 처리해 줬고 요청이 많아지니 메모리 용량에 한계가 있다. 따라서 자바에서는 서블릿을 통해서 해결했다. 서블릿은 프로세스가 아닌 스레드를 생성해서 처리한다. 또한 자바로 이루어져 있어서 GC로 인해 메모리 누수를 걱정하지 않아도 되었다. 이런 서블릿을 관리하는 게 서블릿 컨테이너고 톰캣의 was가 이 서블릿 컨테이너로 이루어져 있다. 서블릿은 init → service → destroy의 생명주기를 갖는다. 톰캣 ..
프로젝트를 한창 할 당시에는 몰랐었지만 추후에 학습하면서 Event처리를 통해 의존성을 끊는 방법을 알았다. 기존의 공식 프로젝트도 외부 api사용 로직을 분리하고 인터페이스를 통해서 의존성을 많이 줄였다고 생각했는데 여전히 불필요한 의존성이 엮여있었다. 프로젝트가 종료된 후, 해당 문제점을 개선하면서 경험을 포스팅을 해봅니다. 문제 정의 임시 저장 게시글을 등록할 시, 임시 저장 게시글 삭제 로직 아래는 게시글 임시 저장 -> 임시 저장된 게시글을 등록 -> 게시글은 저장되고 임시 저장 글은 제거하는 로직입니다. 해당 로직에서 구체적으로 2가지 문제를 가집니다. Article -> TempArticle의 의존성 생성 게시글을 저장하는 로직에서 임시 저장글이 어떻게 처리 되어야 하는지를 알 필요가 없다고..
Java8에서 추가된 Optional은 null을 관리하기 편하게 해주는 객체이다. Optional을 사용하다 보면. orElse() 나 .orElseGet()을 사용한다. 해당 차이점에 대해서 경험한 내용을 적어보려고 한다. orElse() Coupon coupon = couponRepository.findById(1L).orElse(new Coupon()); 위와 같이 Id가 1인 Coupon이 있으면 해당 Coupon을 반환하고 없으면 new Coupon()을 반환하는 로직이다. orElseGet() Coupon coupon = couponRepository.findById(1L).orElseGet(() -> new Coupon()); 위와 같이 람다를 통해 반환하는 모습을 볼 수있다. 즉, orE..
자바는 최상위에 Collection Framework를 가진다. 크게 Collection Framework하위에 Map과 Collection인터페이스로 나뉜다. 컬렉션 프레임워크는 컬렉션을 표현하고 조작하기 위한 통합 아키텍처로, 컬렉션이 구현 세부 사항과 독립적으로 조작될 수 있도록 합니다. 이러한 컬렉션 프레임워크 덕분에 데이터 구조와 알고리즘을 제공하여 직접 작성할 필요가 없는 장점이 있습니다. 또한 컬렉션 인터페이스를 구현함으로써 List, Set, Queue에서는 동일한 api를 사용합니다. ex) add(), clear()... Map Key와 Value의 형태로 이루어진 데이터 집합 순서를 보장하지 않는다. Key는 중복이 허용되지 않고, Value는 중복을 허용한다. 내부적으로 링크드리스트..