프로덕션 애플리케이션 중 하나에서 다소 복잡한 스프링 통합 -amqp 사용 사례가 발생했으며 시작시 "org.springframework.integration.MessageDispatchingException : Dispatcher에 구독자가 없습니다"예외가 발생했습니다. 시작시 초기 오류가 발생하면 동일한 구성 요소에서 예외가 더 이상 표시되지 않습니다. 이것은 AMQP 아웃 바운드 어댑터에 의존하는 구성 요소에 대한 일종의 시작 경쟁 조건과 같아서 수명주기의 초기에 사용하게됩니다.스프링 통합 amqp 아웃 바운드 어댑터 경쟁 조건?
PostConstruct 메서드에서 아웃 바운드 어댑터에 연결된 채널로 보내는 게이트웨이를 호출하여이를 재현 할 수 있습니다.
설정 :
package gadams;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.amqp.Amqp;
import org.springframework.integration.dsl.channel.MessageChannels;
import org.springframework.messaging.MessageChannel;
@SpringBootApplication
@IntegrationComponentScan
public class RabbitRace {
public static void main(String[] args) {
SpringApplication.run(RabbitRace.class, args);
}
@Bean(name = "HelloOut")
public MessageChannel channelHelloOut() {
return MessageChannels.direct().get();
}
@Bean
public Queue queueHello() {
return new Queue("hello.q");
}
@Bean(name = "helloOutFlow")
public IntegrationFlow flowHelloOutToRabbit(RabbitTemplate rabbitTemplate) {
return IntegrationFlows.from("HelloOut").handle(Amqp.outboundAdapter(rabbitTemplate).routingKey("hello.q"))
.get();
}
}
게이트웨이 :
package gadams;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
@MessagingGateway
public interface HelloGateway {
@Gateway(requestChannel = "HelloOut")
void sendMessage(String message);
}
구성 요소 :
내 생산 사용의 경우package gadams;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
@Component
@DependsOn("helloOutFlow")
public class HelloPublisher {
@Autowired
private HelloGateway helloGateway;
@PostConstruct
public void postConstruct() {
helloGateway.sendMessage("hello");
}
}
우리가 사용하고있는 경우, 우리는 PostConstruct의 방법과 구성 요소가 TaskScheduler는 AMQP 아웃 바운드 어댑터에 의존하는 구성 요소와 그 중 일부 구성 요소를 예약합니다. 즉시 실행. 아웃 바운드 어댑터를 사용하고 게이트웨이 및/또는 게이트웨이 자체를 사용하는 빈에 @DependsOn을 사용하는 IntegrationFlows에 콩 이름을 넣으려고했지만 시작시 오류를 제거하지 않았습니다.
github에서 재생산 테스트 케이스를 여기에 올려 놓았습니다. https://github.com/gadams00/rabbit-race – gadams00