javaB2B2C原始碼springmvcmybatis多租戶電子商城系統-Stream重新入隊(RabbitMQ)

it菲菲發表於2019-01-16

本文將介紹RabbitMQ的binder提供的重試功能:重新入隊

準備一個會消費失敗的例子,可以直接沿用前文的工程,也可以新建一個,然後建立如下程式碼的邏輯:

@EnableBinding(TestApplication.TestTopic.class)
@SpringBootApplication
public class TestApplication {

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

    @RestController
    static class TestController {

        @Autowired
        private TestTopic testTopic;

        /**
         * 訊息生產介面
         *
         * @param message
         * @return
         */
        @GetMapping("/sendMessage")
        public String messageWithMQ(@RequestParam String message) {
            testTopic.output().send(MessageBuilder.withPayload(message).build());
            return "ok";
        }

    }

    /**
     * 訊息消費邏輯
     */
    @Slf4j
    @Component
    static class TestListener {

        private int count = 1;

        @StreamListener(TestTopic.INPUT)
        public void receive(String payload) {
            log.info("Received payload : " + payload + ", " + count);
            throw new RuntimeException("Message consumer failed!");
        }

    }

    interface TestTopic {

        String OUTPUT = "example-topic-output";
        String INPUT = "example-topic-input";

        @Output(OUTPUT)
        MessageChannel output();

        @Input(INPUT)
        SubscribableChannel input();

    }

}

內容很簡單,既包含了訊息的生產,也包含了訊息消費。訊息消費的時候主動丟擲了一個異常來模擬訊息的消費失敗。

在啟動應用之前,還要記得配置一下輸入輸出通道對應的物理目標(exchange或topic名)、並設定一下分組,比如:

spring.cloud.stream.bindings.example-topic-input.destination=test-topic
spring.cloud.stream.bindings.example-topic-input.group=stream-exception-handler
spring.cloud.stream.bindings.example-topic-input.consumer.max-attempts=1
spring.cloud.stream.rabbit.bindings.example-topic-input.consumer.requeue-rejected=true
spring.cloud.stream.bindings.example-topic-output.destination=test-topic

完成了上面配置之後,啟動應用並訪問localhost:8080/sendMessage?message=hello介面來傳送一個訊息到MQ中了,此時可以看到程式不斷的丟擲了訊息消費異常。這是由於這裡我們多加了一個配置:spring.cloud.stream.rabbit.bindings.example-topic-input.consumer.requeue-rejected=true。在該配置作用之下,訊息消費失敗之後,並不會將該訊息拋棄,而是將訊息重新放入佇列,所以訊息的消費邏輯會被重複執行,直到這條訊息消費成功為止。


相關文章