[MSA스터디] 3. 공조 마이크로서비스 집합 생성

vector13·2022년 9월 25일
0

기술 요구 사항

책은 mac os 기반으로 진행한다 😓 하지만 나는 윈도우다

사용한 코드는
https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter03에서 다운가능하다.

마이크로서비스 환경 소개

시스템 환경은 복합 서비스인 Product Composite와 핵심 서비스인 Product, Review, Recommendation으로 구성

Product 서비스 (port 7001)

Product 서비스는 제품 정보를 관리
속성 리스트

  • 제품 ID (Product ID)
  • 이름 (Name)
  • 무게 (Weight)

Review 서비스 (port 7002)

리뷰 정보를 관리한다
속성 리스트

  • 제품 ID(Product ID)
  • 검토 ID(Review ID)
  • 작성자(Author)
  • 제목(Subject)
  • 콘텐츠(Content)

Recommendation 서비스 (port 7003)

추천 정보를 관리
속성 리스트

  • 제품 ID (Product ID)
  • 추천 ID (Recommendation ID)
  • 작성자(Author)
  • 평점 (Rate)
  • 콘텐츠(Content)

    Product Composite 서비스 (port 7000)

    핵심 서비스에서 수집한 제품 관련 정보를 제공한다
  • 제품 정보
  • 특정 제품의 리뷰 목록
  • 특정 제품의 추천 목록

마이크로서비스는 어떤 컨테이너가 사용자의 요청에 응답하는지 추적 해야함 (b/c 관리하는 인프라에서 컨테이너로 실행되기 때문) < 추적이 쉽도록 모든 응답에 는 hostname/ip-address:port 형식의 serviceAddress 속성이 추가 >

현 단계 -> 서비스 검색 메커니즘 부재 --> 각 마이크로서비스의 포트 번호를 직접 지정 (=하드 코딩)

골격 마이크로서비스 생성

저자 github에서 코드 clone 중 파일 이름이 너무 길어서 file을 create못하는 문제

Cloning into 'C:\Users\82102\Documents\GitHub\study\Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud'...
remote: Enumerating objects: 3978, done.        
remote: Counting objects: 100% (1051/1051), done.        
remote: Compressing objects: 100% (95/95), done.        
remote: Total 3978 (delta 969), reused 956 (delta 956), pack-reused 2927        
Receiving objects: 100% (3978/3978), 1.08 MiB | 2.72 MiB/s, done.
Resolving deltas: 100% (1842/1842), done.
error: unable to create file Chapter03/2-basic-rest-services/microservices/product-composite-service/src/main/java/se/magnus/microservices/composite/product/ProductCompositeServiceApplication.java: Filename too long
error: unable to create file Chapter03/2-basic-rest-services/microservices/product-composite-service/src/main/java/se/magnus/microservices/composite/product/services/ProductCompositeIntegration.java: Filename too long
error: unable to create file Chapter03/2-basic-rest-services/microservices/product-composite-service/src/main/java/se/magnus/microservices/composite/product/services/ProductCompositeServiceImpl.java: Filename too long
error: unable to create file Chapter03/2-basic-rest-services/microservices/product-composite-service/src/test/java/se/magnus/microservices/composite/product/ProductCompositeServiceApplicationTests.java: Filename too long
error: unable to create file Chapter03/2-basic-rest-services/microservices/recommendation-service/src/main/java/se/magnus/microservices/core/recommendation/services/RecommendationServiceImpl.java: Filename too long
error: unable to create file Chapter03/2-basic-rest-services/microservices/recommendation-service/src/test/java/se/magnus/microservices/core/recommendation/RecommendationServiceApplicationTests.java: Filename too long
Updating files: 100% (2085/2085), done.
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/' 

이는 윈도우 API의 파일 경로 길이가 260자 제한을 갖기 때문임
git config --global core.longpaths true
설정을 추가하고 clone 계속 진행하였음
설정 코드를 보고

https://start.springboot.io/ 에서 프로젝트 생성

그래들에 멀티 프로젝트 빌드 설정

  • settings.gradle 파일을 생성하고 내용 추가
  • product-service 프로젝트에서 그래들 실행 파일을 복사

  • 각 프로젝트에선 그래들 실행 파일이 필요 없으므로 제거한다
    각 프로젝트 가서
    저 네개 삭제

  • 하나의 커맨드로 전체 마이크로서비스를 빌드 가능
    ./gradlew build
    빌드 성공

RESTful API 추가

api 프로젝트와 util 프로젝트 추가

  1. 먼저 API 정의를 배치할 별도의 그래들 프로젝트를 생성
    https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter03/2-basic-rest-services/api

  2. 전체 마이크로서비스가 공유하는 헬퍼 클래스를 배치할 util 프로젝트 생성
    https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter03/2-basic-rest-services/util

  1. api
  • product (product.java, productService.java)
  • recommendation(Recommendation.java, RecommendationService.java)
  • review (Review.java, ReviewService.java)

    getProduct() 메서드 : 일반 POJO 기반 모델 클래스인 Product 객체를 반환
  1. util
  • 예외 클래스인 InvalidInputException과 NotFoundException
  • 유틸리티 클래스인 ServiceUtil, GlobalControllerExceptionHandler, HttpErrorInfo

api 구현

  1. microservices/product-service/build.gradle 파일의 의존성 요소에 api 및 util 프로젝트를 추가
implementation project(':api')
implementation project(':util')
  1. ProductServiceApplication 클래스에 @ComponentScan("se.magnus") 추가

  2. ProductServiceImpl.java를 생성

  3. util 프로젝트의 ServiceUtil 클래스 주입

  4. ProductService 인터페이스의 getProduct() 메서드를 재정의해 API를 구현

  5. 포트 번호 및 로깅 수준과 같은 런타임 속성을 설정한다.
    microservices/product-service/src/main/resources/application.yml

server.port: 7001
server.error.include-message: always

logging:
  level:
    root: INFO
    se.magnus: DEBUG
  1. product 서비스를 직접 실행
    ./gradlew build
    java -jar microservices/product-service/build/libs/*.jar &
  • 빌드 관련 에러
  • 에러 원인 예상
    에러 메세지에
    A problem occurred evaluating project ':microservices:product-service'.
    Project with path ':api' could not be found in project ':microservices:product-service'.
    라고 되어있는데

api 폴더가 밖에 있는데 ':microservices:product-service'에서 찾고있음
그럼 build.gradle 설정을 내가 잘못해줬다고 예상

책에서 나온것처럼 product-service에 잇는 build.gradle에만
include ':api'
include ':util' 을 주지 않고
기존 루트 프로젝트의 settings.gradle에도 추가를 해주었다.

include ':api'
include ':util'
include ':microservices:product-service'
include ':microservices:review-service'
include ':microservices:recommendation-service'
include ':microservices:product-composite-service'
  • 다음 에러 (어노테이션 못알아먹는)

    cannot find symbo
    @ComponentScan("se.magnus")
  • 예상 에러 원인

위에 import 리스트를 보면 보통 어노테이션 추가할 때 import 되어야하는데 자동으로 안됐을 거라고 추정
import org.springframework.context.annotation.ComponentScan;
추가해줬음

다시 빌드해보면 성공

다음 명령어
java -jar microservices/product-service/build/libs/*.jar & 입력하려했는데

& 문자를 못쓴다

  • 다음 에러

그래서 & 을 빼고
java -jar microservices/product-service/build/libs/*.jar 를 시도

Error: Unable to access jarfile microservices/product-service/build/libs/*.jar

  • 예상 에러 원인
    cmd 에서 열어서 관리자권한으로 시도하면 될거라고 생각

    여전히 안됨
    해당 경로에 jar 가 있는지 확인
    있는데도 왜 안될까

  • 해결
    해당 폴더에있는 jar 파일이 2개 이므로 plain을 제외하고 위에있는것을 직접적으로 지정해주었음

curl 명령어도 잘된다.

복합 마이크로서비스 추가

이제 세 가지 핵심 서비스를 호출하는 복합 서비스를 추가해 여러 마이크로서비스를 하나로 묶는다.

책임을 나누는 복합 서비스의 구현은

  • 핵심 서비스로의 발신 요청을 처리하는 통합 컴포넌트와
  • 복합 서비스 자체 구현의 두 부분으로 나뉜다.

==> 단위 테스트와 통합 테스트를 간편하게 자동화하고 통합 컴포넌트를 모의 객체(mock)로 대체해 서비스 구현을 개별적으로 테스트하기 위함.
(책임 분담하면 서킷 브레이크 쉽게 도입 가능)

API 클래스

https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter03/2-basic-rest-services/microservices/product-composite-service/src/main/java/se/magnus/microservices/composite/product/services


microservices/product-composite- service/src/main/resources/application.yml

server.port: 7000
server.error.include-message: always

app:
  product-service:
    host: localhost
    port: 7001
  recommendation-service:
    host: localhost
    port: 7002
  review-service:
    host: localhost
    port: 7003

logging:
  level:
    root: INFO
    se.magnus: DEBUG

통합 컴포넌트

@Component 애노테이션 ProductCompositeIntegration.java

ProductCompositeServiceApplication.java에 추가

@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}

복합 API 구현

ProductCompositeServiceImpl.java

예외 처리 추가

https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter03/2-basic-rest-services/util/src/main/java/se/magnus/util/exceptions
전역 REST 컨트롤러 예외 핸들러와 API 구현의 예외 처리

api 수동 테스트

마이크로서비스의 수동 테스트 단계
1. 마이크로서비스를 빌드하고, 백그라운드 프로세스로 시작.
2. curl로 복합 API를 호출, 종료.

  1. ./gradlew build

java -jar microservices/product-composite-service/build/libs/product-composite-service-0.0.1-SNAPSHOT.jar &
java -jar microservices/product-service/build/libs/product-service-0.0.1-SNAPSHOT.jar &
java -jar microservices/recommendation-service/build/libs/recommendation-service-0.0.1-SNAPSHOT.jar &
java -jar microservices/review-service/build/libs/review-service-0.0.1-SNAPSHOT.jar &

  1. curl http://localhost:7000/product-composite/1

자동화된 마이크로서비스 테스트

테스트할 비즈니스 로직이 많지 않으므로 단위 테스트는 작성하지 않고 마이크로서비스의 공개 API를 집중적으로 테스트

  • 에러 : junit 관련 import 에러

  • 아직 미해결 ..

정리 및 느낀점

정리

3장은 공조 마이크로서비스 집합 생성 공조 마이크로서비스 집합을 생성하는 방법을 설명했다.

스프링부트로 product, review, recommendtaion 세 가지 핵심 서비스를 만들고, 웹플럭스를 사용해 API를 추가했고, 세 가지 핵심 서비스의 API로 정보를 집계하는 복합 서비스를 구현했다.
복합 서비스는RestTemplate 클래스를 사용해 핵심 서비스가 공개한 API로 HTTP request를 보내고, 예외처리 로직 추가한 후 수동테스트와 전체 서비스 테스트를 진행했다.

느낀점

공조 마이크로서비스가 도대체 뭘까 고민 많이했는데 아마도 서로 도우면서 서비스하는 뜻의 공조[共助], cooperation 또는 mutual assistance의 번역투이지 않을까 싶었다.
스프링 프로젝트에서 그래들에 멀티 프로젝트 빌드는 처음이라 에러를 많이 겪었지만 이것저것 경험해볼 수 있어서 좋았다.

profile
HelloWorld! 같은 실수를 반복하지 말기위해 적어두자..

0개의 댓글