본문 바로가기

전체 글

(103)
CQRS패턴 도입 이야기: CQRS 구현 방법 도입부 저번 글에서 왜 CQRS를 이용해야 하는지에 대해 알아봤다. 본 글은 이전 글에 이어서 CQRS를 구현하는 방법에 대해서 알아보고자 한다. 구현 형태 일반적으로 다음 그림과 같은 형태로 구현이 된다. DB 개념은 조회와 명령의 DB가 같을 경우 다를 경우를 의미하고 프로세스 개념은 조회와 명령이 같은 서버에 있는지 다른 서버에 있는지를 의미한다. ㅡ> 마이크로 서비스 아키텍처(MSA) 구조와 연관되어있다. 1. 같은 프로세스 같은 DB 가장 단순한 경우며, 코드적으로만 분리한 경우이다. 2. 같은 프로세스, 다른 DB DB도 분리했기 때문에 DB 간에 일관성을 위해 명령 DB 변경시 변경이 전파되어야 한다. 3. 같은 프로세스, 같은 DB, 다른 테이블 이 경우 조회용 테이블을 따로 두어 성능을 ..
CQRS패턴 도입 이야기: CQRS 패턴이란? 글을 쓰게 된 계기 앞서 elasticsearch를 적용한 글을 보면 알 수 있듯이, 상품 도메인에 대해서 조회용 저장소, 명령용 저장소가 분리되어 있다. 하지만 코드적으로는 분리되어 있지 않기 때문에 클래스의 책임이 모호한 상태이다. 따라서 CQRS 패턴을 적용함으로써 요구사항이 추가되더라도 확장에 용이하고 클래스가 이전보다 더 확실한 책임을 가질 수 있도록 하고자 한다. 더 나아가 이 이야기의 핵심인 Kafka를 통해 두 저장소 간의 데이터 일관성을 맞추는 과정을 설명할 계획이다. CQRS란 무엇일까? 영어 뜻 그대로 CQRS란 명령(시스템의 데이터 변경) 역할을 수행하는 구성 요소와 쿼리(시스템 데이터 조회) 역할을 수행하는 구성 요소를 나누는 것을 의미한다. 간단한 예시 코드를 통해 살펴보자 요약..
Elasticsearch 적용 이야기: Kibana 적용기 키바나를 적용한 계기 주문은 매출과 직결되는 중요한 도메인이기 때문에 주문 통계의 필요성을 느꼈다. 이에 엘라스틱 서치에서 지원하는 강력한 모니터링 도구인 키바나를 적용하고자 한다. 적용과정 1. 먼저 현재 내가 사용하고 있는 elasticsaerch의 버전에 맞는 kibana 이미지를 다음의 명령어로 설치한다. 2. 다음으로 키바나 컨테이너를 실행하기에 앞서 키바나 컨테이너와 엘라스틱 서치의 컨테이너의 연동을 위해 엘라스틱 서치 컨테이너의 id를 확인한다. 3. 환경변수에 2에서 확인한 컨테이너 id를 --link 옵션으로 연결시킨 후 키바나 컨테이너를 실행한다. (이외에도 컨테이너간 통신하는 방법은 있으니 다른 방법을 이용해도 된다.) 4. localhost:5601 포트에 접속해서 인덱스 패턴을 생..
Elasticsearch 도입 이야기: 성능 테스트 하기 처음 ES를 적용한 목적이 올바르게 달성했는지 확인하기 위해 ES와 RDBMS의 조회 성능을 비교해보는 코드를 작성해봤다. 1. 데이터 삽입 1.1 RDBMS에 데이터 넣기 먼저 RDBMS에 1만개의 데이터를 넣었다. 코드는 다음과 같다. 간단하게 for문을 이용해 넣었으며 1만개의 데이터를 RDBMS에 넣는데 239.622초 걸린 것을 확인할 수 있다. 1.2 ES에 데이터 넣기 다음으로 ES에 데이터를 넣었다. 코드는 다음과 같다. 총 337.457초 걸렸으며 RDBMS보다 40%정도 느리다. 예상대로 ES가 데이터를 역 인덱스로 저장하기 때문에 저장시 더 오래 걸리는 것을 확인할 수 있다. 2. 데이터 조회 데이터 조회에 앞서 엘라스틱 서치와 MySQL의 성능 차이를 확실하게 하기위해 데이터를 약 ..
Elasticsearch 도입 이야기: 스프링 부트와 연동하기 지난 글에 이어 elasticsearch를 적용하는 글을 작성해보겠다. 1. Elasticsearch 설치 $ docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.0 $ docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.10.0 docker를 통해 elasticsearch를 설치한다. 나의 경우 최신 버전에 대한 사용법이 익숙치 않아 7.10.0 버전을 설치했다. 실행은 싱글 노드로 실행되도록 설정했다. 내부에서는 노드간 9300포트로 통신한다는 의미로 -p 9300:9300을 설정..
Elasticsearch 도입 이야기: Elasticsearch란? ES를 적용하게 된 계기 위의 기사만 봐도 알 수 있듯이 우리는 조회하는 작업과 생성하는 작업 중 조회하는 작업을 압도적으로 많이 한다. 예를 들어 뉴스 기사, 블로그 글을 보더라도 1개의 생성물에 수많은 조회를 한다. 이에 나는 프로젝트에서 조회가 많이 발생하는 도메인에 조회 전용의 리포지토리가 있으면 좋겠다는 생각을 하게 됐다. 따라서 검색에 특화되어 있는 검색엔진인 elasticsearch를 적용하게 됐다. elasticsearch란 Elasticsearch는 Apache Lucene 기반의 Java 오픈소스 분산형 RESTful 검색 및 분석 엔진이다. JSON 문서(Document)로 데이터를 저장하기 때문에 정형 데이터, 비정형 데이터, 지리 데이터 등 모든 타입의 데이터를 처리할 수 있다. ..
소셜로그인에 팩토리 메소드 패턴 적용하기 고민사항 OAuth를 통해 로그인을 구현할 때 해당 OAuth 로그인을 제공하는 api의 주체가 어느 회사인지 판단하는 로직을 Dto 객체에서 하고 있다. 해당 역할을 Dto 객체가 하는게 맞는지에 대한 의문과 함께 굳이 이 로직을 if-else문을 사용해야 할까? 라는 고민을 하였다. 결론적으로, 팩토리 메소드 패턴을 적용하는게 알맞다는 생각을 갖게 돼 해당 디자인 패턴으로 리팩토링 하였다. 기존의 코드 @Getter public class OAuthAttributes { private Map attributes; private String nameAttributeKey; private String name; private String email; private String picture; @Build..
전략패턴을 이용한 리팩토링 문제점 현재 팩토리 메소드 패턴을 이용해 결제 시스템의 확장을 생각하며 구현하였다. 기존의 코드를 살펴보면 다음과 같다. 결제 종류를 인자로 받아 알맞은 결제 url로 리다이렉트 시켜주는 방법이다. 다음은 결제 종류가 담겨있는 팩토리 클래스이다. 현재 카카오페이만 구현한 상태이므로 종류에는 kakao 만 있다. 해당 클래스는 결제 종류를 인자로 받아 알맞은 구현체를 반환한다. 인터페이스 코드 구현체 코드 컨트롤러의 코드를 보면 알 수 있듯이, 팩토리에서 구현체를 반환했지만 구현체를 이용하지 않고 경로만 redirect 시켜주는 일만 한다. 따라서 생성 패턴이 아닌 행동 패턴을 적용하는게 적당해 보인다. 이에 사용자의 입력에 따라 결제의 행위를 적용시킬 수 있도록 전략패턴을 통해 구현했다. 리팩토링 개선된..