포스트

LG CNS 부트캠프 학습일지 49일차

학습 내용

  • OpenFeign을 사용해서 마이크로서비스 간 통신하기
  • Kafka를 사용해서 마이크로서비스 간 자료를 동기화시키기

OpenFeign을 사용해서 마이크로서비스 간 통신하기

어제는 RestTemplate을 사용해서 마이크로서비스 간에 데이터를 주고 받는 방법을 배웠다. 메소드에 이것 저것 전달해야하는 것이 많았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserServiceImpl implements UserService {
    RestTemplate restTemplate;
	
	@Override
    public UserDto getUserByUserId(String userId) {
        ...
		
        String orderUrl = String.format(env.getProperty("order-service.url"), userId);
        ResponseEntity<List<ResponseOrder>> orderListResponse = 
			restTemplate.exchange(orderUrl, HttpMethod.GET, null, ...);
        List<ResponseOrder> orderList = orderListResponse.getBody();
        userDto.setOrders(orderList);

        return userDto;
    }
}

하지만 OpenFeign은 이것조차 할 필요가 없도록, 사용하기 쉽게 만들어져있다.

1
2
3
4
5
6
@FeignClient(name="order-service", configuration = FeignErrorDecoder.class)
public interface OrderServiceClient {

    @GetMapping("/order-service/{userId}/orders")
    List<ResponseOrder> getOrders(@PathVariable String userId);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class UserServiceImpl implements UserService {
    OrderServiceClient orderServiceClient;

	...
	
    @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);
        List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
        userDto.setOrders(orderList);

        return userDto;
    }
}

OpenFeign을 사용하면 getOrder() 메소드를 구현하지 않아도 된다. 이 메소드를 호출하면 Order Service의 특정 엔드포인트에 접근한다는 것을 적는 것으로 끝난다.

Kafka를 사용해서 마이크로서비스 간 자료를 동기화시키기

각 마이크로서비스는 하나의 서버가 아니라 여러 개의 인스턴스로 구성되어 있다. 각 인스턴스가 별도의 데이터베이스를 관리하고 있다면 인스턴스들의 데이터베이스를 동기화시켜 주어야 하는 문제가 발생한다. 이 때 각 인스턴스가 서로 네트워크 요청과 응답을 주고받게 할 수도 있지만 메세지 큐잉 시스템을 사용해서 메세지가 모이고 흩어지는 곳을 만든다면 조금 더 효율적으로 관리할 수 있을 것이다. 이를 위해 사용하는 것이 Kafka이다. RabbitMQ 사용법에 대해서 배울 때 Kafka라는 것이 있다고 배웠었다. 오늘 이것을 직접 사용해봤다.

도커를 사용해서 Kafka 서버를 구축했다.

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
32
33
34
services:
  kafka:
    image: apache/kafka:4.3.1
    container_name: kafka
    hostname: kafka

    ports:
      - "9092:9092"

    environment:
      # Node configuration
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller

      # Listener configuration
      KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT

      # Cluster configuration
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk

      # Single-node settings
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1

    volumes:
      - data:/var/lib/kafka/data
	  
volumes:
  data:

자랑할 것은 아니지만 인공지능에게 docker-compose.yml 파일을 만들어달라고 시켰다. 솔직히 말해 environment 안에 있는 설정 값들이 왜 필요한지 그리고 어떤 영향이 있는지는 모르겠다. 지금으로서는 Kafka 서버를 만들어서 상호작용하는 방법을 배웠다는 것에 의의를 두어야겠다. 아래 명령어를 사용해서 Kafka 컨네이터 쉘에 들어갔다.

1
docker-compose exec kafka bash
1
2
3
4
cd /opt/kafka
bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092
bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092
bin/kafka-topics.sh --delete --topic quickstart-events --bootstrap-server localhost:9092

Kafka 컨터이너 안에 있는 스크립트 파일을 실행해서 토픽을 새로 만들고 확인하고 삭제했다. 토픽을 만든 상태로 아래 명령어들을 실행했다.

1
2
bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092
bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092

실습을 할 때는 Kafka 컨테이너의 쉘을 여러 개 열었다. 그리고 하나는 프로듀서, 그리고 다른 하나는 컨슈머 명령어를 실행해서 프로듀서에서 보낸 메세지가 컨슈머에서 받아지는지를 확인했다. 명령어랑 옵션들이 익숙하지는 않지만, Kafka를 통해 한 쪽에서 보낸 메세지를 다른 쪽에서 읽어들일 수 있다는 것을 확인했다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Comments powered by Disqus.