본문 바로가기

분류 전체보기

(67)
헥사고날 아키텍처(Hexagonal Archtecture) 이번 포스팅은 헥사고날 아키텍쳐에 대해서 알아볼 예정이며 필자의 경우 해당 아키텍쳐에 대해서 지식을 습득한 이후 토이 프로젝트에 적용 해볼 생각이다.   헥사고날 아키텍처란?헥사고날 아키텍쳐는 응용 프로그램의 비지니스 로직을 외부 세계로부터 격리시켜 유여한고 테스트가 쉬운 구조를 만드는 것입니다.이를 위해 핵심 비지니스 로직은 중앙의 도메인 영역에 위치하며, 입력과 출력을 처리하는 포트와 어댑터를 통해 외부와 소틍을 합니다. 해당 아키텍쳐의 핵심은 도메인과 비지니스 로직을 외부 요소에 의존하지 않고, 프레젠테이션 계층, 데이터 소스 계층 같은 외부 요소들이 도메인에 의존하도록 만듭니다. 위의 내용으로 프로그래머는 아래와 같은 효과를 볼 수 있습니다.관심사의 분리를 통하여 외부 요소에 영향을 받지 않고 비..
Spring Boot Batch 적용하기 - 3 배치는 대용량 데이터를 처리하기 위한 도구로 유용하게 사용되고 있습니다. 스프링 배치를 사용하며 다양한 기능에 대한 효과를 볼 수 있습니다. 배치에 성능도 필요하게되면 우리는 병렬 처리를 고민해 볼 수 있습니다. 스프링 배치는 다양한 병렬 방식을 제공해주고 있으며 이번 포스팅에서는 스프링 부트 병렬 방식에 대해서 알아보겠습니다.  Spring Batch Chunk 병렬 처리 방식 1. AsyncItemProcessor AsyncItemProcessor는 process로직을 병렬 처리하는 방식입니다. (spring-batch-integration 의존성이 별도로 필요)process의 처리 결과로 Future를 반환하고 Writer에서 Future의 결과를 종합하여 처리합니다.  기존 Processor, W..
Spring Scope와 ObjectProvider, proxyMode Bean Scope 스프링은 빈이라는 개념으로 자바 객체를 만들고 싱글톤화 시켜 관리하여 줍니다.이 객체들은 스프링 IoC 컨테이너의 의해 생성되고 소멸되는 등의 관리가 이루어 집니다. 이때 bean이 관리되는 범위를 Bean scope라고 합니다.여기서 bean이 싱글턴화 되서 관리되는 이유는 spring bean의 기본 scope 전략이 Singleton 이기 때문입니다.  scope설명singleton하나의 Bean 정의 대해서 Spring Container 내에 단 하나의 개객체만 존재한다.prototype하나의 Bean 정의에 대해서 다수의 객체가 존재할 수 있다.request하나의 Bean 정의에 대해서 하나의 HTTP request의 생명 주기 안에 단 하나의 객체만 존재한다.즉, 각각의 H..
Spring Boot Batch 적용하기 - 2 1. Step Skip Step 처리 도중에서 설정한 Exception이 발생하게 되면 해당 데이터를 건너뛰는 기능입니다.데이터의 작은 오류에 대해서 Step 의 실패 처리 대신 Skip 을 함으로써 배치 수행의 빈번한 실패를 줄일 수 있습니다.Skip 제한을 초과하는 경우가 되면 Exception이 발생됩니다. ItemReaderitem 을 읽던 도중 예외가 발생하게 되면 해당 item 을 skip 하고 다음 item 을 읽습는다. ItemProcessoritem 을 처리하던 도중 예외가 발생하면 해당 Chunk 의 첫 단계로 돌아가서 itemReader로부터 다시 데이터를 전달받습니다.itemProcessor 는 다시 item 을 받아 실행하는데 이전 실행에서 발생한 예외 정보가 내부적으로 남아있어 ..
Spring Boot Batch 적용하기 - 1 1. 스프링 배치 (Spring Batch) 스프링 배치(Spring Batch)는 대용량 데이터를 처리하기 위한 프레임워크로 스프링 기반에서 동작합니다.대량의 데이터를 효율적으로 처리하기위 해다양한 기능을 제공해줍니다.  로깅 및 추적작업 처리 통계작업 재시작건너뛰기/리소스 관리트랜잭션 관리위 와같이 대용량 데이터 처리를 안정적으로 처리를 제공해줍니다.스프링 배치(Spring Batch) 위와 같은 아키텍쳐 구성을 가지고 있습니다. ※ Batch 와 Scheduler 차이배치(Batch)는 논리적 또는 물리적으로 구성된 데이터를 그룹화하여 일괄 처리하는 방법을 의미합니다. 스케줄러(Scheduler)는 주어진 작업을 정의된 시간에 수행할 수 있게 도와주는 도구를 의미합니다. 배치는 대량의 데이터를 일괄..
Spring Boot + Quartz 적용하기 - 3 앞서 Spring Boot + Quartz 스케줄링을 구현해보았습니다.해당 포스팅은 클러스팅 환경에서 동작할 수 있게 구현해보았습니다.  1. Quartz 데이터베이스 생성Quartz 클러스터 환경을 구축하기 위해서는 메타 정보를 관리하는 데이터베이스를 생성해 주어야한다. 인텔리제이를 사용하는 사용자는 아래처럼 sql을 찾아서 테이블을 생성해주면 됩니다. 아래처럼 스키마를 구성해주면 됩니다. 이후 application.yml에 아래와 같이 설정해주었습니다. 2. quartz properties 설정이제는 quartz properties 설정을 해주면 됩니다. datasource를 설정해주고 클러스팅 처리 설정을 ture로 진행해주세요.우리는 클러스터링 환경을 구성하기 위하여 JDBC JobStore를 선..
Spring Boot + Quartz 적용하기 - 2 앞서 Quartz에 대해서 개념을 알아보았다해당 포스팅은 Spring Boot  + Quartz를 활용하여 스케줄링을 구현해보겠습니다.    1. SchdulerJob과 Trigger를 연결하여 Job을 실행시키는 역할을 수행하는 인터페이스입니다.Spring + Quartz 사용으로 ApplicationContext에 의해 관리되는 SchedulerFactoryBean을 생성해주었다.SchedulerFactoryBean에 JobFactory를 등록하여 Job도 컨텍스트로 관리될수 있게 설정된다. package com.kr.quartz.config;import com.kr.quartz.listener.MyJobListener;import com.kr.quartz.listener.TriggerListener..
Spring Boot + Quartz 적용하기 - 1 Spring Boot + Quartz를 이용하여 스케줄링 적용 과정을 포스팅하였습니다. 1. 스케줄링(Scheduling) 이란? 스케줄러란 일정한 주기 마다 반복적으로 작업을 실행하는 도구를 일컫는 말이다. 개발을 진행하는 과정에서 주기적으로 실행해야하는 작업이 필요한 경우가 생긴다. 이러한 경우 스케줄링 설정을 이용하여 작업을 처리할 수 있다. 자바에서는 다양한 스케줄러를 지원하게되는데 Quartz, Spring Scheduler, ScheduledExecutorService 등이 존재합니다.  ※ 배치 스케줄링(Batch Scheduling) 이란?배치 스케줄링이란 대량의 데이러터 처리를 자동화 작업으로 구현것을 의미합니다. 이번장에서는 배치 스케줄링을 적용하지 않으며 추후에 스프링 배치 포스팅을 ..
CPU 과부화 장애 트러블슈팅 개인적으로 구성해둔 미니 PC 서버에서 이상감지가 되었다. Zabbix를 통하여 간단하게 서버 리소스 상태만 감지하고 있었는데 어느날 부터 갑자기 CPU 점유가 100%가 넘어가기 시작하며, 나중에는 서버가 죽어버렸다. 일단 서버를 재부팅하였고 다시 리소스가 정상화 되었으며 트러블 슈팅을 하기로 생각했다. 위 그림을 보면 CPU 점유가 100%가 넘었고 장애가 발생되었다. 실제로 운영하는 서비스가 저렇게 되면 대형사고와 마찬가지다. 일단 개인적으로 구축한 서비스들이 전부다 지연이 되었고 동작 불가상태까지 넘어갔다.  첫 째로 현재 CPU 상태를 보기 위하여 서버 상태를 체크하였고 위 스크린샷을 보면 알 수 있듯이 특정 PID (39521)이 말도안되는 높은 CPU 점유를 가지고 있었다.해당 PID cmd..
gitHub & Jenkins CI/CD 적용 (4/4) 이전 포스팅에서 진행했던 마지막 CI/CD 배포를 진행할 예정입니다.  필자 경 Pipeline script를 작성하여 배포를 진행하였습니다. 작성 배포 스크립트 포맷pipeline { agent any tools { gradle 'gradle-8.7' } environment { DCOKER_IMAGE_NAME = ""; } stages { stage('git pull') { environment { REPOSITORY_URL = "" } steps { git branch: 'main', url: "${REPOSITORY_URL}"..