使用Rabbitmq了解春季云消息传递

时间:2018-08-18 11:09:12

标签: java spring spring-boot rabbitmq spring-messaging

我认为我在理解春季云消息传递方面遇到问题,无法找到我面临的“问题”的答案。

我有以下设置(使用spring-boot 2.0.3.RELEASE)。

application.yml

spring:
    rabbitmq:
      host: localhost
      port: 5672
      username: guest
      password: guest
      virtual-host: /
    cloud:
      stream:
        bindings:
          input:
            destination: foo
            group: fooGroup
          fooChannel:
            destination: foo

服务等级

@Autowired
FoodOrderController foodOrderController;

@Bean
public CommandLineRunner runner() {
    return (String[] args) -> {
       IntStream.range(0,50).forEach(e -> foodOrderController.orderFood());
    };
}

@StreamListener(target = FoodOrderSource.INPUT)
public void processCheapMeals(String meal){
    System.out.println("This was a great meal!: "+ meal);
}

@StreamListener(target = FoodOrderSource.INPUT)
public void processCheapMeals1(String meal){
    System.out.println("This was a great meal!: "+ meal);
}

FoodOrderController

public class FoodOrderController {

    @Autowired
    FoodOrderSource foodOrderSource;

    public String orderFood(){
        var foodOrder = new FoodOrder();
        foodOrder.setCustomerAddress(UUID.randomUUID().toString());
        foodOrder.setOrderDescription(UUID.randomUUID().toString());
        foodOrder.setRestaurant("foo");
        foodOrderSource.foodOrders().send(MessageBuilder.withPayload(foodOrder).build());
       // System.out.println(foodOrder.toString());
        return "food ordered!";
    }
}

FoodOrderSource

public interface FoodOrderSource {
    String INPUT = "foo";
    String OUTPUT = "fooChannel";

    @Input("foo")
    SubscribableChannel foo();
    @Output("fooChannel")
    MessageChannel foodOrders();
}

FoodOrderPublisher

@EnableBinding(FoodOrderSource.class)
public class FoodOrderPublisher {
}

除两个StreamListener接收相同的消息外,该设置正在运行。因此,所有内容都会记录两次。阅读文档时,它说在队列绑定中指定group,这两个侦听器都将在组内注册,并且只有一个侦听器会收到一条消息。我知道上面的示例不明智,但是我想模仿具有多个侦听器设置的多节点环境。

为什么两个侦听器都收到该消息?以及如何确保在安装组中仅收到一次消息?

根据文档,消息在默认情况下也应自动确认,但是我找不到任何指示消息实际上已得到确认的信息。我在这里想念东西吗?

这是Rabbit admin的一些屏幕截图

enter image description here enter image description here enter image description here enter image description here enter image description here

2 个答案:

答案 0 :(得分:2)

  

在阅读文档时,它说在队列绑定中指定一个组,这两个侦听器都将注册在该组内,并且只有一个侦听器会收到一条消息。

当侦听器位于不同的应用程序实例中时,这是正确的。当同一实例中有多个侦听器时,它们都将收到相同的消息。这通常与condition一起使用,每个听众都可以在其中表达对他们感兴趣的饭菜的兴趣。Documented here

基本上,竞争的使用者是绑定本身,它会将消息分发到应用程序中的实际@StreamListener

因此,您不能通过这种方式“模拟具有多个侦听器设置的多节点环境”。

  

但是我找不到任何表明消息已被确认的信息

那是什么意思?如果成功处理了该消息,则容器将对该消息进行确认并将其从队列中删除。

答案 1 :(得分:1)

帖子中已经给出了正确答案的答案,但是您仍然可以查看以下内容:

https://github.com/jinternals/spring-cloud-stream