SW/마이크로서비스

마이크로서비스 : 서비스 간 연계 구현 : 방법, 개념, 개요

얇은생각 2020. 5. 30. 07:30
반응형

마이크로서비스 : 서비스 간 연계 구현 : 방법, 개념, 개요

 

쇼피몽 서비스 업무 흐름 

마이크로서비스들 간의 동기 및 비동기 연동 기능을 구현해서 고객이 상품을 구매하는 쇼핑몰 시스템의 주요 프로세스를 구현하고 테스트해 보았습니다. 이 쇼핑몰 시스템의 여러 업무 중 상품 구매를 위한 프로세스를 구현합니다. 이 프로세스를 좀 더 자세히 설명하면, 구매자가 상품구매를 위해 구매할 상품과 수량을 입력하면 Account 서비스로 구매자에 해당하는 주소정보를 조회해서 가져옵니다. Product 서비스로 구매하려는 상품의 가격정보를 조회해서 가져옵니다.

구매자가 가져온 주소와 상품의 가격을 확인하고 최종 구매를 결정하면, 이 정보가 배송 서비스로 전달됩니다. 이 상품 구매 프로세스를 동작하게 하기 위한 각 서비스간의 동기 및 비동기 방식의 연동 기능을 구현하고 테스트합니다.

 

 

Account Service 구매자 조회 API 추가

구매자가 상품 구매를 위해 구매할 상품과 수량을 입력하면, Account 서비스로 구매자에 해당하는 주소정보를 조회해서 가져옵니다. 이 기능을 위해 Account 서비스에 구매자를 조회할 수 있는 REST API를 추가해 보도록 하겠습니다. 보통 쇼핑몰은 아이디와 비밀번호를 입력해서 로그인 한 후 상품 구매를 하게 됩니다.

구매자가 상품을 구매하는 경우 Account 서비스로 로그인한 사용자의 아이디에 해당하는 정보를 요청하는 것이 일반적입니다. 그러나 로그인 기능 없이 간단하게 구현하고 있으므로 입력 받은 Account 서비스로 사용자의 이름에 해당하는 정보를 요청하도록 구현하였습니다. 작성한 내용을 작성한 내용을 저장하고 Account 프로젝트를 Build합니다. 오류 없이 Build가 끝나면 Boot Dashboard 창의 shop-account를 선택해서 시작시킵니다.

서버가 실행되면 Swagger UI를 실행해서 확인해 보았습니다. 웹브라우저에서 Localhost의 Swagger-ui로 접근해보면 JPA에서 자동으로 생성한 메서드를 볼 수 있었는데 방금 AccountRepository에 추가한 FindByName이라는 REST API가 추가된 것을 확인할 수 있습니다.

 

 

Product Service 상품 조회 API 추가

또한 구매자가 상품구매를 위해 구매할 상품과 수량을 입력합니다. Product 서비스로 구매할 상품에 해당하는 상품정보를 조회해서 가져왔습니다. 이 기능을 위해 Product 서비스에 구매하려는 상품을 조회할 수 있는 REST API를 추가해 보았습니다.

Account 서비스에서 일반적으로 구매 서비스는 상품의 아이디를 통해 상품정보를 조회합니다. 편의와 데이터의 가독성을 위해 Product 서비스로 상품 이름으로 상품정보를 요청하도록 구현하였습니다. 추가한 내용을 저장하고 Product 프로젝트를 Build합니다. 마찬가지로 오류 없이 Build가 끝나면 Boot Dashboard 창에서 Shop-product를 선택해서 시작시킵니다.

마찬가지로 서버가 실행되면 Swagger UI를 실행해서 확인했습니다. Product 서비스는 11002 포트를 사용하기로 했으므로 웹브라우저에서 Localhost의 11002번 포트로 접근합니다. 이 Swagger UI를 보면 JPA에서 자동으로 생성한 메서드를 볼 수 있습니다. 방금ProductRepository 추가한 FindByName이라는 REST API가 생성된 것을 확인할 수 있습니다.

 Purchase 서비스에서 고객이름으로 Account 서비스 내의 정보를 요청하기 위해서 Account로 FindByName을 통해 요청한 Account의 정보를 수신해서 저장할 AccountDTO를 생성합니다. 다른 마이크로서비스와의 연계는 Proxy를 통해 연계하므로 Account 서비스와 연계를 위한 AccountProxy를 생성합니다. 그리고 Purchase의 서비스 로직에서 Account 서비스의 API를 호출하기 위한 인터페이스를 정의하고 이 인터페이스의 구현체를 구현합니다.

Purchase의 서비스 로직이 Account 서비스의 API를 호출하기 위한 준비가 완료되었습니다. 그럼 Purchase 서비스에서 구매는 다음의 순서로 진행됩니다. 먼저 Account 서비스에서 고객이름으로 Account 서비스 내의 정보를 요청하기 위해 구현한 AccountProxy의 FindByName 함수를 호출해서 파라미터로 설정한 이름에 해당하는 회원의 정보를 전달받아 로컬변수에 저장합니다.

 

 

Purchase Service 상품 조회 기능 추가

이번에는 Purchase 서비스에서 상품이름으로 Purchase 서비스 내의 정보를 요청하기 위해서 Purchase 서비스로 FindByName을 통해 요청한 상품 정보를 수신해서 저장할 ProductDTO를 생성합니다. Product 서비스와의 연계도 Account 서비스 연계를 설정했던 방법과 같이 Purchase의 서비스 로직에서 Product 서비스의 API를 호출하기 위한 인터페이스를 정의합니다. 이 인터페이스의 구현체를 구현하는 것으로 Product 서비스를 호출할 준비를 마칩니다.

Product 서비스의 경우도 Account 서비스와 동일하게 구현이 가능하며, 먼저 Purchase 서비스에서 상품이름으로 Product 서비스 내의 정보를 요청하기 위해 구현한 ProductProxy의 FindByName 함수를 호출해서 파라미터로 설정한 이름에 해당하는 상품정보를 전달받아 로컬변수에 저장합니다. 이렇게 Purchase 서비스와 Account 서비스, Product 서비스 간의 동기 방식의 연동 기능을 구현합니다.

 

 

구매 프로세스 구성도

쇼핑몰 시스템의 서비스 간 업무흐름을 나타내는 구성도를 보면, Purchase 서비스는 구매가 이루어지면 구매 데이터를 저장하고 구매내역의 발생을 큐로 전달합니다. 그러면 이 큐를 구독하던 Delivery 서비스는 이 구매내역 발행 이벤트를 수신해서 Delivery 서비스의 데이터에 저장합니다.

이후 실제 쇼핑몰 서비스라면 배송업체를 통해 갱신되는 배송상태를 Delivery 서비스를 통해 구매자에게 제공합니다. 그럼 Purchase 서비스에서 상품 구매가 발생했다는 이벤트를 발행합니다. 또 이 이벤트를 Delivery 서비스에서 수신하는 비동기 연동 기능을 구현합니다.

 

 

Purchase Service 구매 이벤트 발행 기능 추가

ActiveMQ를 활용해서 마이크로서비스 간 비동기 연동 기능을 구현하였습니다. 먼저 ActiveMQ를 설치합니다. ActiveMQ는 최신 버전을 다운로드 받고, 압축을 해제한 후 실행만 하면 됩니다. 그럼 ActiveMQ 사용으로 위해 프로젝트의 Pom 파일에 Dependency를 추가합니다.

Config 패키지에 ActiveMQConfig 클래스를 스프링 부트 프로젝트에 추가합니다. ActiveMQ 사용을 위한 설치와 설정 그리고 프로젝트에 Maven Dependency의 설정이 끝나면 구매가 발행했다는 이벤트를 정의합니다. Purchase의 서비스 로직에 구매가 발생했다는 이벤트를 발행하는 모듈을 구현합니다.

 

 

Delivery Serivce 구매 이벤트 구독 기능 추가

Delivery 서비스에서는 구매가 발생되었다는 이벤트를 구독합니다. 이벤트가 발생됨을 확인하면 이 이벤트를 수신해서 수취자 이름과 주소, 상품 이름 등을 전달받아 배송 시스템으로 전달하게 됩니다. 그러나 배송시스템은 구현하지 않으므로 이 이벤트를 수신하는 것까지 확인합니다.

구독을 위해 Delivery 서비스에 Purchase 서비스와 동일하게 ActiveMQ 사용을 위한 Config와 PurchaseCompleted 이벤트를 동일하게 추가합니다. 또한 서비스 로직에 Purchase로 부터 수신한 구매 정보를 받아 저장소에 저장하기 위한 기능과 수취자가 상품을 받고 수취 확인을 하면 배송 목록에서 삭제하기 위한 기능을 추가합니다. 그리고 이벤트를 수신하기 위한 ActiveMQReceiver를 추가합니다.

 

 

구매 프로세스 동작 테스트

그럼 Account와 Product에 초기 데이터를 생성한 후 Purchase에서 구매 프로세스를 진행합니다. 데이터의 추가는 각 서비스의 Swagger UI를 통해 POST 메서드를 사용해서 추가합니다. 물론 Swagger UI의 GET 메서드나 각 서비스에서 사용하는 데이터베이스를 통해 생성한 데이터의 확인이 가능합니다.

Purchase 서비스에서 구매 내역 발생시키려면 별도 컨트롤러를 구현해야 하는데, 테스트 편의를 위해 Application Main에서 구매를 발생시킵니다. 이렇게 해서 서비스 로직의 Order가 실행되면 Account에 입력한 이름에 해당하는 Account 정보를 받아옵니다. 상품 이름에 해당하는 Product 정보를 받아와 이 이벤트를 생성합니다.

이후 Delivery 서비스의 Swagger UI를 통해 PurchaseCompleted 이벤트를 수신해서 Delivery의 저장소에 저장한 정보를 확인합니다. 이 과정을 통해 마이크로서비스 구현을 위한 주요 개념들과 클라우드 기반의 애플리케이션을 만들기 위한 내/외부 아키텍처에 대해 이해합니다. 또한 간단한 예제를 통해 하나의 시스템을 이벤트 스토밍 기법을 활용한 워크샵을 통해 여러 개의 마이크로서비스를 도출해 보았습니다. 각 마이크로서비스를 도메인 주도 설계 기법을 활용해서 도메인 모델링도 해보았습니다.

이렇게 설계된 마이크로서비스를 실제 코드로 구현해보고 또 각 마이크로서비스 간 동기/비동기 연계 기능을 추가해서
전략적 설계를 통해 도출했던 비즈니스 프로세스에 따라 각 마이크로서비스가 연계해서 동작하는 것을 확인했습니다. 마이크로서비스의 설계를 도메인 주도 설계의 전략적 설계 및 전술적 설계 방식을 따라 진행했습니다.

그렇지만 마이크로서비스의 구현을 항상 도메인 주도 설계 방식으로만 설계해야 되는 것은 아닙니다. 마이크로서비스 아키텍처에 가장 바람직한 구조 및 설계 방식을 '도메인 주도 설계'라 보고, 이 기법을 채택해서 설명하고 있습니다. 그러나, 프로젝트 상황이나 업무 성격에 따라 도메인주도설계의 전략적 설계를 기반으로 마이크로서비스를 도출하되, 마이크로서비스의 내부구조는 도메인주도설계의 전술적 패턴을 적용하지 않은 구조로도 설계할 수 있습니다.

반응형