Apache Camel RabbitMQ端点上的竞争消费者

时间:2018-05-03 08:06:08

标签: rabbitmq apache-camel

enter image description here

我有一个服务的四个精确副本,使用Apache Camel RabbitMQ端点从某个队列捕获消息。每条路线都是这样的:

//Start Process from RabbitMQ queue
    from("rabbitmq://" +
            System.getenv("ADVERTISE_ADDRESS") +
            "/" +
            System.getenv("RABBITMQ_EXCHANGE_NAME") +
            "?routingKey=" +
            System.getenv("RABBITMQ_ROUTING_KEY") +
            "&autoAck=true")
            .process(exchange -> exchange.getIn().setBody(exchange.getIn().getBody()))
            .unmarshal().json(JsonLibrary.Jackson, TwitterBean.class)
            .transform().method(ResponseTransformer.class, "transformtwitterBean")
            .marshal().json(JsonLibrary.Jackson)
            .setHeader(Exchange.HTTP_METHOD, constant("POST"))
            .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
            .to("http4://" + System.getenv("ADVERTISE_ADDRESS") + ":" + System.getenv("CAMUNDA_PORT") + "/rest/process-definition/key/MainProcess/start")
            .log("Response: ${body}");

现在每个端点都处理该消息。 即使"并发消费者"默认选项是一个。 我以为我的信息可能没有被承认, 所以我将autoAck选项设置为true。

这没有帮助,我怎样才能让这些服务与消费者竞争呢?

编辑:

我的发布商应用配置中的代码段:

@Configuration
public class RabbitMqConfig {
    @Bean
    Queue queue() {
        return new Queue(System.getenv("RABBITMQ_QUEUE_NAME"), true);
    }

    @Bean
    DirectExchange exchange() {
        return new DirectExchange(System.getenv("RABBITMQ_EXCHANGE_NAME"), true, true);
    }

    @Bean
    Binding binding(Queue queue, DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(System.getenv("RABBITMQ_ROUTING_KEY"));
    }

    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    public AmqpTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        return rabbitTemplate;
    }
}

2 个答案:

答案 0 :(得分:1)

您遇到的问题是您没有在服务端命名您的队列

基于camel apache rabbitmq documentation,这意味着为队列生成随机名称。

所以:

  • 您的发布商会向交换
  • 发送消息
  • 然后,您的每个服务都会创建一个带有随机名称的队列绑定到交换机

每个拥有自己队列的服务,绑定到同一个交换机,都会得到相同的消息。

为避免这种情况,您需要提供队列名称, 这样每个服务都将连接到相同的队列,这意味着他们将与其他服务实例共享消息消费。

答案 1 :(得分:0)

听起来像你没有队列,但有主题。请参阅here进行比较。

消息代理负责向一个消费者提供队列消息,无论其中有多少消息存在。