티스토리 뷰

MSA

Section 10: 마이크로서비스간 통신

✨✨✨✨✨✨✨ 2023. 6. 7. 17:58
반응형
Communication types
RestTemplate
Feign Client - Log, Exception
ErrorDecoder
Multiple Orders service

 

Rest Template

사용자가 user Info 뿐만아니라 orders의 정보도 함께 알고 싶을경우,

REST Template를 통하여 USER Service가 Order Service에게 요청 하고 응답을 받는다

 

~/msa-config/user-servie-dev.yml

order_service:
  url: <http://ORDER-SERVICE/%s/orders>

order_service.url 값을 다음과 같이 설정한다.

user-service - UserServiceApplication.java

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @LoadBalanced //추가
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

@LoadBalanced 를 추가하고 getRestTemplate을 Bean으로 등록한다.

user 요청 시 다음 메소드에 List<ResponseOrder> 를 가지고 올 경우, RestTemplate를 이용하여 요청으로 받아낸다.

@Override
public UserDto getUserByUserId(String userId) {
    UserEntity userEntity = userRepository.findByUserId(userId);
    if(userEntity == null)
        throw new UsernameNotFoundException("User not found");

    UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
    String orderUrl = String.format(env.getProperty("order_service.url"), userId);
    ResponseEntity<List<ResponseOrder>> orderResponses = restTemplate.exchange(orderUrl, HttpMethod.GET
            , null, new ParameterizedTypeReference<>() {
            });

    List<ResponseOrder> orderList = orderResponses.getBody();
    userDto.setOrders(orderList);

    return userDto;
}

 


FeignErrorDecoder

위 방식은 FeignClient Exception이 발생(FeignException)하였을 경우, 하나씩 try~catch문으로 감싸주었다.

그것은 너무 번거롭기에 아래 Bean으로 등록해주면 다음과 같이 사용하여도 FeignExceptio을 잡아주어 try~catch로 감싼 효과를 얻을 수 있다.

@Component
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()));
                }
                break;
            default:
                return new Exception(response.reason());
        }
        return null;
    }
}

@Component로 등록한 FeignErrorDecoder는 FeignException를 잡아준다.

@Override
    public UserDto getUserByUserId(String userId) {
        UserEntity userEntity = userRepository.findByUserId(userId);
        if(userEntity == null)
            throw new UsernameNotFoundException("User not found");

        UserDto userDto = new ModelMapper().map(userEntity, UserDto.class);
				
				// FeignErrorDecoder 생성 전 FeignClient Exception 처리
				//        List<ResponseOrder> orderList = new ArrayList<>();
				//        try {
				//            // Using a feign client
				//            orderList = orderServiceClient.getOrders(userId);
				//        } catch (FeignException e){
				//            log.error(e.getMessage());
				//        }

        List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
        userDto.setOrders(orderList);
        return userDto;
    }

getOrders 는 없는 order-service의 url을 요청하기에 다음과 같이 FeignException이 발생하고 이를

FeignErrorDecoder가 잡아준다.

 

2023-06-04 12:57:50.368  WARN 74905 --- [o-auto-1-exec-1] 
.w.s.m.a.ResponseStatusExceptionResolver : 
Resolved [org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND]

 


Multiple Orders Service

Kafka Connector + DB

OrderService를 여러개 띄우면서 하나의 DB에 데이터 저장 시 동기화문제가 생길 수 있다. 그렇기에 Message Queuing Server(Kafka)를 사용하여 미들웨어를 넣고 데이터를 동기화 시킨다.

  1. 데이터 충돌: 여러 OrderService 인스턴스가 동일한 주문 데이터를 동시에 업데이트하려고 할 때 데이터 충돌이 발생할 수 있습니다. 예를 들어, 두 개의 인스턴스가 동시에 주문 상태를 변경하면 어느 상태가 최종 상태인지 명확하지 않을 수 있습니다.
  2. 중복 데이터: 여러 OrderService 인스턴스가 동시에 동일한 주문 데이터를 처리하려고 할 때, 중복된 데이터`가 데이터베이스에 저장될 수 있습니다. 이로 인해 주문이 중복으로 처리되거나 잘못된 결과가 발생할 수 있습니다.
  3. 데이터 일관성: 여러 OrderService 인스턴스가 동시에 데이터베이스에 변경을 수행할 때, 데이터의 일관성이 깨질 수 있습니다. 예를 들어, 한 인스턴스가 주문을 삭제하고 다른 인스턴스가 해당 주문을 수정하려는 경우, 데이터베이스에 불일치가 발생할 수 있습니다.
  4. 동시성 문제: 여러 OrderService 인스턴스가 동시에 동일한 데이터를 조회하거나 업데이트하려고 할 때, 동시성 문제가 발생할 수 있습니다. 이는 예기치 않은 결과를 초래할 수 있으며, 데이터의 정합성을 보장하기 어렵게 만들 수 있습니다.

자, 그럼 어떤 동기화 문제가 발생하는지 궁금하니 아래와 같이 order-service를 2개 띄운다

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함