如何在spring amqp中设置basicQos以进行公平调度?

时间:2014-05-19 07:10:05

标签: java spring rabbitmq spring-amqp

这是我目前的春季amqp配置

<rabbit:connection-factory id="rabbitConnectionFactory"
    port="${rabbitmq.port}" host="${rabbitmq.host}" username="${rabbitmq.username}" password="${rabbitmq.password}"/>

<rabbit:admin id="rabbitmqAdmin" connection-factory="rabbitConnectionFactory" />

<rabbit:template id="importAmqpTemplate"
    connection-factory="rabbitConnectionFactory">
</rabbit:template>

这是我的交流,队列,监听器,replyQueues,replyHandlers配置

<rabbit:queue name="${process1.queue}" />
<rabbit:queue name="${process1.reply.queue}" />

<rabbit:queue name="${process2.queue}" />
<rabbit:queue name="${process2.reply.queue}" />

<rabbit:direct-exchange name="${myExchange}">
    <rabbit:bindings>
        <rabbit:binding queue="${process1.queue}"
            key="${process1.routing.key}" />
        <rabbit:binding queue="${process2.queue}"
            key="${process2.routing.key}" />
    </rabbit:bindings>
</rabbit:direct-exchange>

<rabbit:listener-container
    connection-factory="rabbitConnectionFactory" concurrency="${my.listener.concurrency}"
    requeue-rejected="false">
    <rabbit:listener queues="${process1.queue}"
        ref="foundation" method="process1" />
    <rabbit:listener queues="${process2.queue}"
        ref="foundation" method="process2s" />
</rabbit:listener-container>


<beans:beans profile="master">

    <beans:bean id="process1Lbq" class="java.util.concurrent.LinkedBlockingQueue" />
    <beans:bean id="process2Lbq" class="java.util.concurrent.LinkedBlockingQueue" />

    <beans:bean id="process1sReplyHandler"
        class="com.stockopedia.batch.foundation.ReplyHandler"
        p:blockingQueue-ref="process1Lbq" />

    <beans:bean id="process2ReplyHandler"
        class="com.stockopedia.batch.foundation.ReplyHandler"
        p:blockingQueue-ref="process2Lbq" />

    <rabbit:listener-container
        connection-factory="rabbitConnectionFactory" concurrency="1"
        requeue-rejected="false">
        <rabbit:listener queues="${process1.reply.queue}"
            ref="process1sHandler" method="onMessage" />
        <rabbit:listener queues="${process2.reply.queue}"
            ref="process2ReplyHandler" method="onMessage" />
    </rabbit:listener-container>

</beans:beans>

我已经在6台不同的服务器上设置了它,并且仅从主服务器排队消息。其他服务器仅处理消息。所有服务器都具有相同数量的侦听器,并且由并发运行。

问题是,消息需要不同的时间来处理。有些消息需要很长时间。因此,目前一些服务器不会从队列中获取消息,即使这些服务器上的所有侦听器都处理完消息。

我可以看到要处理的队列中的待处理消息和一些闲置的服务器。我希望这些服务器在其他服务器忙于处理其消息时获取剩余消息。

我是否需要按照教程http://www.rabbitmq.com/tutorials/tutorial-two-java.html(公平调度)中的说明设置basic_Quos?

int prefetchCount = 1;
channel.basicQos(prefetchCount);

或者它是弹簧放大器的默认值吗?如果不是我该怎么办?

1 个答案:

答案 0 :(得分:1)

basicQos(1)是侦听器容器的默认设置;可以通过在容器上设置prefetch来更改它。

  

我可以看到要处理的队列中的待处理消息和一些闲置的服务器。

如果您有闲置的消费者,您不应该看到刚刚排队的消息。如果消息被标记为未确认,则正在处理它们。

如果启用DEBUG级别日志记录,您将能够看到空闲的消费者轮询内部队列以获取新的交付。