클러스터를 통해 hystrix 스트림의 정보를 집계하는 방법은 turbine을 사용하면 가능하였다. 하지만 이러한 집계(aggregation) 방법은 pull-based 방식이기 때문에 turbine 인스턴스가 각 인스턴스에게 스트림을 요청하게 된다. 이러한 방식은 인스턴스가 늘어날 때 마다 turbine에게 부담을 주게 된다. 그리고 일부 환경(ex: PaaS)에서는 모든 분산 Hystrix command를 가져오는 turbine이 작동하지 않을 때도 존재한다.
이러한 문제점을 해결하기 위해서 Spring Cloud Turbine AMQP가 제공 되며, 각 어플리케이션 인스턴스가 직접 중앙 RabbitMQ 브로커에게 정보를 제공하며 이러한 정보를 받은 RabbitMQ가 turbine으로 메트릭 정보를 푸시(push-based)하게 된다.
1. 준비
해당 샘플 프로젝트는 아래와 같이 총 5개로 구성이 되어 있으며 RabbitMQ의 경우 차후 컨테이너화를 대비해 도커로 구성해 본다.
turbine dashboard application
turbine stream application
RabbitMQ
Service application
Eureka application
2. Docker Rabbit MQ 실행
에서 rabbitmq 이미지를 받는다.
management ui를 사용하기 위해서 3.7.5-management tag를 받는다.(2018/06/18 기준 최신)
$ docker pull rabbitmq:3.7.5-management
이미지를 받았으면 컨테이너를 실행한다. (위 다운 작업 없이 아래 명령어를 실행하면 로컬에 해당 이미지가 없을 경우 자동으로 pull 한 이후에 실행한다)
위에서 @Output 안에 주는 값은 application.yml에 작성하였던 bindings 중 하나의 이름과 동일하다.
반대로 @Input 어노테이션도 가능하며 MessageChannel 대신 SubscribableChannel을 사용한다.
이제 위의 커스텀채널을 호출하는 컴포넌트를 아래와 같이 작성한다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
@Component
public class Sender {
@Autowired
Processor processor;
public void send(String message) {
processor.anOutPut().send(message(message));
}
private static final <T> Message<T> message(T val) {
return MessageBuilder.withPayload(val).build();
}
}
이 상태로 실행을 하게 되면 서버가 실행이 되지 않는데 왜냐하면 해당 어플리케이션에 Input 및 Output을 작성한 커스텀채널을 브로커에 바인딩이 가능하도록 spinrg에게 알려줘야 하기 때문이다. 따라서 아래와 같은 @EnableBinding 어노테이션을 추가한다.
import hystrix.amqp.service.message.Processor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.stream.annotation.EnableBinding;
@EnableHystrix
@SpringBootApplication
@EnableEurekaClient
@EnableBinding(Processor.class)
public class RabbitMQApplication {
public static void main(String[] args) {
SpringApplication.run(RabbitMQApplication.class, args);
}
}
4. Turbine Stream Application 작성
위에서 작성한 어플리케이션에서 rabbitmq의 exchange로 보낸 메시지들을 취합하는 turnbine 어플리케이션을 작성한다.
만약 위의 단계까지 했단 rabbitmq의 management ui에서 exchagne만 생성이 되고 queue는 생성되지 않는 것을 확인 할수 있는데
여기서 Turbine Stream application을 작성하면 queue가 생성되는 것을 볼 수 있다.