서비스 디스커버리와 클라이언트 사이드 로드 밸런싱을 활용한 마이크로서비스 통신

날아올라돼지야·2024년 8월 28일

이번 챕터에서는 Eureka 서버를 사용하여 마이크로서비스 네트워크 내에서 클라이언트 사이드 서비스 디스커버리와 로드 밸런싱이 어떻게 작동하는지 설명하고, 이를 데모로 보여줍니다. 이 과정에서 Accounts 마이크로서비스에 새로운 REST API를 구축하여, 고객의 카드, 대출, 계좌 정보를 통합하여 반환하는 기능을 구현합니다. 이 API는 Accounts 마이크로서비스가 LoansCards 마이크로서비스와 통신하여 데이터를 수집하는 데 사용됩니다.

주요 단계

  1. 의존성 추가:

    • Accounts 마이크로서비스의 pom.xml 파일에 OpenFeign 의존성을 추가합니다.
    • 다음과 같이 의존성을 추가합니다:
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-openfeign</artifactId>
      </dependency>
    • Maven 변경 사항을 로드하여 OpenFeign 라이브러리를 다운로드합니다.
  2. Feign 클라이언트 활성화:

    • AccountsApplication 클래스에 @EnableFeignClients 어노테이션을 추가하여 Feign 클라이언트를 활성화합니다.
    • 이는 Accounts 마이크로서비스가 다른 마이크로서비스(예: Loans, Cards)와 통신할 수 있도록 해줍니다.
  3. Feign 클라이언트 인터페이스 생성:

    • com.eazybytes.accounts.service.client 패키지에 새로운 인터페이스를 생성합니다.
    • CardsFeignClient 인터페이스를 생성하여 Accounts 마이크로서비스가 Cards 마이크로서비스와 통신할 수 있도록 합니다.
      @FeignClient("cards")
      public interface CardsFeignClient {
          @GetMapping("/api/fetch")
          List<CardsDto> fetchCardDetails(@RequestParam("mobileNumber") String mobileNumber);
      }
    • @FeignClient("cards") 어노테이션은 Cards 마이크로서비스가 Eureka에 등록된 논리적 이름(cards)을 기반으로 해당 마이크로서비스를 찾도록 해줍니다.
    • 유사한 방식으로 LoansFeignClient 인터페이스도 생성하여 Loans 마이크로서비스와 통신할 수 있게 합니다.
  4. DTO 클래스 추가:

    • CardsDtoLoansDto 클래스를 Accounts 마이크로서비스의 dto 패키지에 복사하여 추가합니다.
    • 이는 각 Feign 클라이언트가 각 마이크로서비스와 통신할 때 사용될 데이터 전송 객체를 정의합니다.
  5. Feign 클라이언트 설정 완료:

    • Accounts 마이크로서비스는 이제 CardsLoans 마이크로서비스와 통신할 준비가 되었습니다.
    • Feign 클라이언트는 @FeignClient 어노테이션과 메소드 시그니처를 통해 자동으로 해당 마이크로서비스와의 통신을 처리합니다.

코드 예시

  • FeignClient 예시:

    @FeignClient("cards")
    public interface CardsFeignClient {
        @GetMapping("/api/fetch")
        List<CardsDto> fetchCardDetails(@RequestParam("mobileNumber") String mobileNumber);
    }
    
    @FeignClient("loans")
    public interface LoansFeignClient {
        @GetMapping("/api/fetch")
        List<LoansDto> fetchLoanDetails(@RequestParam("mobileNumber") String mobileNumber);
    }
  • CardsController 예시:

    @RestController
    public class CardsController {
        @GetMapping("/api/fetch")
        public List<CardsDto> fetchCardDetails(@RequestParam("mobileNumber") String mobileNumber) {
            // Implementation here
        }
    }
  1. DTO 클래스 생성:

    • Accounts 마이크로서비스에 CustomerDetailsDto 클래스를 생성하여 고객의 계좌, 카드, 대출 정보를 통합하여 저장할 수 있도록 합니다.
    • CustomerDetailsDtoCustomerDto, AccountsDto, LoansDto, CardsDto 등의 정보를 포함합니다.
    @Data
    @Schema(name = "CustomerDetails", description = "Schema to hold customer, account, cards and loans information.")
    public class CustomerDetailsDto {
        private String name;
        private String email;
        private String mobileNumber;
        private List<AccountsDto> accounts;
        private List<LoansDto> loans;
        private List<CardsDto> cards;
    }
  2. Feign Client 인터페이스 사용:

    • 이전 강의에서 생성한 LoansFeignClientCardsFeignClient 인터페이스를 사용하여 Accounts 마이크로서비스가 다른 마이크로서비스와 통신할 수 있도록 합니다.
    • 이러한 인터페이스를 CustomerServiceImpl 클래스에 주입하고, 이를 통해 다른 마이크로서비스로부터 데이터를 가져옵니다.
    @Service
    @AllArgsConstructor
    public class CustomerServiceImpl implements ICustomerService {
        private final AccountsRepository accountsRepository;
        private final CustomerRepository customerRepository;
        private final LoansFeignClient loansFeignClient;
        private final CardsFeignClient cardsFeignClient;
    
        @Override
        public CustomerDetailsDto fetchCustomerDetails(String mobileNumber) {
            // 고객 정보와 계좌 정보 가져오기
            Customer customer = customerRepository.findByMobileNumber(mobileNumber);
            List<Accounts> accounts = accountsRepository.findByCustomerId(customer.getId());
    
            CustomerDetailsDto customerDetails = new CustomerDetailsDto();
            customerDetails.setName(customer.getName());
            customerDetails.setEmail(customer.getEmail());
            customerDetails.setMobileNumber(customer.getMobileNumber());
            customerDetails.setAccounts(AccountsMapper.mapToAccountsDto(accounts));
    
            // Feign Client를 사용하여 대출 및 카드 정보 가져오기
            List<LoansDto> loans = loansFeignClient.fetchLoanDetails(mobileNumber).getBody();
            List<CardsDto> cards = cardsFeignClient.fetchCardDetails(mobileNumber).getBody();
            customerDetails.setLoans(loans);
            customerDetails.setCards(cards);
    
            return customerDetails;
        }
    }
  3. 컨트롤러 구현:

    • CustomerController를 생성하여 고객의 모든 정보를 통합한 결과를 반환하는 API를 구현합니다.
    • 이 API는 Accounts 마이크로서비스가 LoansCards 마이크로서비스와 통신하여 얻은 데이터를 통합하여 클라이언트에게 반환합니다.
   @RestController
   @RequestMapping("/api")
   @Validated
   public class CustomerController {
       private final ICustomerService customerService;

       @GetMapping("/fetchCustomerDetails")
       public ResponseEntity<CustomerDetailsDto> fetchCustomerDetails(
           @RequestParam("mobileNumber") @Pattern(regexp = "^\\d{10}$", message = "Invalid mobile number") String mobileNumber) {
           CustomerDetailsDto customerDetails = customerService.fetchCustomerDetails(mobileNumber);
           return ResponseEntity.ok(customerDetails);
       }
   }
  1. API 테스트:

    • 모든 마이크로서비스를 시작한 후, Postman을 사용하여 새로 만든 API를 테스트합니다.
    • /api/fetchCustomerDetails 경로로 GET 요청을 보내면, 고객의 모든 정보(계좌, 대출, 카드)가 통합되어 반환됩니다.
    {
        "name": "John Doe",
        "email": "john.doe@example.com",
        "mobileNumber": "1234567890",
        "accounts": [...],
        "loans": [...],
        "cards": [...]
    }

주요 개념 요약

  • Feign 클라이언트는 구현 코드를 작성할 필요 없이 간단한 인터페이스와 어노테이션만으로 다른 마이크로서비스와 통신할 수 있습니다.
  • Feign 클라이언트는 Eureka 서버와 통신하여 대상 마이크로서비스의 인스턴스 정보를 얻고, 로드 밸런싱을 통해 요청을 처리합니다.
  • OpenFeign을 사용하면 REST API 호출과 관련된 많은 반복적인 코드를 줄일 수 있으며, 마이크로서비스 간 통신을 더욱 효율적으로 관리할 수 있습니다.
  • Eureka 서버는 서비스 디스커버리와 로드 밸런싱을 자동으로 처리하여, 마이크로서비스 간의 통신을 보다 간단하고 효율적으로 만듭니다.
  • 이러한 접근 방식은 마이크로서비스가 서로 통신할 때 안정성과 확장성을 보장합니다.

이번 챕터를 통해 Accounts 마이크로서비스가 LoansCards 마이크로서비스와 통신하여 고객 정보를 통합하는 방법을 학습했습니다. 이 과정에서 Feign ClientEureka 서버를 활용하여 서비스 디스커버리와 로드 밸런싱을 구현하였으며, 이러한 설정을 통해 마이크로서비스 간의 통신이 어떻게 이루어지는지를 이해할 수 있었습니다.

profile
무슨 생각하며 사니

0개의 댓글