[MSA] Spring Cloud로 MSA를 개발해보자 9편 [서비스간 통신-2]

2024. 8. 30. 00:27· Java/Spring Boot
목차
  1. 1.  FeignClient
  2. 1). 구현
  3.  
  4. 2). Feign Client에서 로그 사용
  5. 3). Feign Client에서 예외처리
  6.  
  7. 4). FeignErrorDecoder
  8. 2. Multiple Orders Service [데이터 동기화 문제]

FeignClient

- REST Call을 추상화 한 Spring Cloud Netflix 라이브러리

 

1.  FeignClient

1). 구현

OrderServiceClient.java

@FeignClient(name = "order-service")
public interface OrderServiceClient {

    // 다 퍼블릭이라서 따로 적을 필요는 없다
    @GetMapping("/order-service/{userId}/orders")
    List<ResponseOrder> getOrders(@PathVariable String userId);

}

 

UserServiceImpl.java

 @Override
    public UserDto getUserByUserId(String userId) {
        UserEntity userEntity = userRepository.findAllByUserId(userId);

        if (userEntity == null)
            throw new UsernameNotFoundException("User not found");

        UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);

        /* feing client 첫번째 사용 */
        /* Feign exception handling */
        List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);

        userDto.setOrders(orderList);

        return userDto;
    }

 

 

FeignClient로 데이터 가져오기 성공

 

2). Feign Client에서 로그 사용

application.yml

logging:
  level:
    com.example.userservice.client: DEBUG

 

Bean 등록

@Bean
	public Logger.Level feignLoggerLevel() {
		return Logger.Level.FULL;
	}

 

3). Feign Client에서 예외처리

// 오타를 내보자
@GetMapping("/order-service/{userId}/orders-ng")
    List<ResponseOrder> getOrders(@PathVariable String userId);

기본 상태

 

UserServiceImpl.java

   @Override
    public UserDto getUserByUserId(String userId) {
        UserEntity userEntity = userRepository.findAllByUserId(userId);

        if (userEntity == null)
            throw new UsernameNotFoundException("User not found");

        UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);

        /* feing client 첫번째 사용 */
        /* Feign exception handling */
        List<ResponseOrder> orderList = null;
        try {
            orderServiceClient.getOrders(userId);
        } catch (FeignException ex) {
            log.error(ex.getMessage());
        }

        userDto.setOrders(orderList);

        return userDto;
    }

 

 

사용자 정보는 제대로 가져왔고 주문 정보는 출력되지 않음

 

4). FeignErrorDecoder

- decode는 페인 클라이언트에서 발생한 에러가 어떤 에러가 발생했는지 상태코드를 가지고 분기되어 있는 적절한 코드를 나눠서 작업할 수 있게 해준다.

 

Bean 등록

@Bean
	public FeignErrorDecoder getFeignErrorDecoder() {
		return new FeignErrorDecoder();
	}

 

FeignErrorDecoder.java

public class FeignErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        switch (response.status()) {
            case 400:
                break;
            case 404:
                if (methodKey.contains("getOrders")) {
                    return new ResponseStatusException(HttpStatus.valueOf(response.status()),
                            "User's orders is empty.");
                }
                break;
            default:
                return new Exception(response.reason());
        }
        return null;
    }
}

 

UserServiceImpl.java

    @Override
    public UserDto getUserByUserId(String userId) {
        UserEntity userEntity = userRepository.findAllByUserId(userId);

        if (userEntity == null)
            throw new UsernameNotFoundException("User not found");

        UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);

        /* ErrorDecoder */
        List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
        userDto.setOrders(orderList);

        return userDto;
    }

 

 

클래스에서 하드코딩을 하는게 아니라 설정파일에 내용을 가져오는 방식으로 해보겠다

 

config-service 지정된 폴더에 설정파일 [user-service.yml] 코드 추가

order_service:
  url: http://ORDER-SERVICE/order-service/%s/orders
  // 추가된 부분
  exception:
    orders_is_empty: User's orders is empty.

 

// UserServiceApplication.java에서 Bean 삭제 [컴포넌트로 선언했기 때문]
// FeignErrorDecoder.java
@Component
public class FeignErrorDecoder implements ErrorDecoder {

    Environment env;

    @Autowired
    public FeignErrorDecoder(Environment env) {
        this.env = env;
    }

    @Override
    public Exception decode(String methodKey, Response response) {
        switch (response.status()) {
            case 400:
                break;
            case 404:
                if (methodKey.contains("getOrders")) {
                    return new ResponseStatusException(HttpStatus.valueOf(response.status()),
                            env.getProperty("order_service.exception.orders_is_empty"));
                }
                break;
            default:
                return new Exception(response.reason());
        }
        return null;
    }
}

 

 

 

2. Multiple Orders Service [데이터 동기화 문제]

Orders Service 2개 기동

- Users의 요청 분산 처리

 

- Orders 데이터도 분산 저장 -> 동기화 문제

 

- 하나의 Database 사용 -> 물리적으로 떨어진 인스턴스에서 생기는 하나의 DB에 저장하기 위해선 트랜잭션을 잘 관리해야됨

 

- 각각의 Database를 사용하고 DB간 동기화 -> 1번 Orders Service에서 발생한 데이터를 2번 Order Service가 가지고 있으면 됨. Message Quing Server을 사용함

 

- Kafka Connector + DB -> 하나의 DB와 Message Quing Server을 같이 사용

 

 

Order-Service  2개 기동

 

한명의 사용자가 5건의 상품을 주문했을 때 1번과 2번 서버가 번갈아가며 DB에 저장되어 있다. 다음시간에 알아보겠다.

1번 Order-service에 3건

2번 Order-service에 2건

'Java > Spring Boot' 카테고리의 다른 글

[MSA] Spring Cloud로 MSA를 개발해보자 11편 [Kafka-2]  (0) 2024.09.06
[MSA] Spring Cloud로 MSA를 개발해보자 10편 [Kafka-1]  (0) 2024.09.01
[MSA] Spring Cloud로 MSA를 개발해보자 8편 [서비스간 통신-1]  (1) 2024.08.29
[MSA] Spring Cloud로 MSA를 개발해보자 7편 [설정 정보 암호화]  (0) 2024.08.28
[MSA] Spring Cloud로 MSA를 개발해보자 6편 [Spring Cloud Bus]  (1) 2024.08.27
  1. 1.  FeignClient
  2. 1). 구현
  3.  
  4. 2). Feign Client에서 로그 사용
  5. 3). Feign Client에서 예외처리
  6.  
  7. 4). FeignErrorDecoder
  8. 2. Multiple Orders Service [데이터 동기화 문제]
'Java/Spring Boot' 카테고리의 다른 글
  • [MSA] Spring Cloud로 MSA를 개발해보자 11편 [Kafka-2]
  • [MSA] Spring Cloud로 MSA를 개발해보자 10편 [Kafka-1]
  • [MSA] Spring Cloud로 MSA를 개발해보자 8편 [서비스간 통신-1]
  • [MSA] Spring Cloud로 MSA를 개발해보자 7편 [설정 정보 암호화]
누리는 귀여워
누리는 귀여워
안녕하세요, 누리 사료값을 벌기 위해 앞으로 나아가는 아버지의 개발 블로그입니다.
누리는 귀여워
누리아버지
누리는 귀여워
전체
오늘
어제
  • 분류 전체보기 (76)
    • Java (0)
      • Spring Boot (16)
      • JPA (1)
    • JavaScript (1)
      • React.js (1)
    • DataBase (3)
      • PostgreSQL (2)
    • DevOps (2)
      • MSA (1)
      • Docker (1)
    • OS (9)
    • Network (0)
    • CS 지식 (0)
    • Error 모음집 (0)
    • 코딩테스트 (32)
      • 기초 (31)
      • 알고리즘 (1)
    • 기타 (7)
    • 쉼터 (2)
      • 잡담 (2)
      • 하루 마무리 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • postman
  • kafka connect
  • Boot
  • kafka sink connect
  • 인텔리제이
  • Kafka
  • war 배포
  • spring boot
  • GATEWAY
  • MSA
  • Docker
  • spring cloud
  • Oracle Cloud
  • postgresql
  • eureka
  • 깃허브연동
  • Dockerfile
  • centos
  • git bash
  • JPA

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
누리는 귀여워
[MSA] Spring Cloud로 MSA를 개발해보자 9편 [서비스간 통신-2]
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.