Spring integration - Queue/Poller seems to exhaust threadpool without any action

后端 未结 2 1306
深忆病人
深忆病人 2020-12-21 04:47

I have a Spring integration app, attached to an AMQP broker.

I want to receive messages from an amqp-queue, and update db records.

In order to improve perfor

相关标签:
2条回答
  • 2020-12-21 04:54

    Rather than using a QueueChannel and poller, why not simply increase the concurrent-consumers attribute on the inbound adapter?

        <xsd:attribute name="concurrent-consumers" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation>
    Specify the number of concurrent consumers to create. Default is 1.
    Raising the number of concurrent consumers is recommended in order to scale the consumption of messages coming in
    from a queue. However, note that any ordering guarantees are lost once multiple consumers are registered. In
    general, stick with 1 consumer for low-volume queues.
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    

    And, remove the <queue/> and <poller/>.

    Also, I always recommend including the thread name in the log (%t for log4J); it makes it easier to debug threading issues.

    EDIT:

    With the poller, the reason you are running out of threads is the poller has a default receive-timeout of 1 second. You are scheduling a thread every 50ms, but each then waits in the QueueChannel for 1 second. Eventually your task queue fills up.

    To avoid this, simply set the receive-timeout to 0 on the <poller/> if you wish to continue with this technique - but using higher concurrency in the adapter is more efficient because there's no polling or handover to another thread.

    0 讨论(0)
  • 2020-12-21 05:14

    It appears I needed a bridge to map between the amqp-inbound queue (which is a pub/sub style queue), and a queue-channel.

    <int-amqp:inbound-channel-adapter queue-names="pricehub.fixtures.priceUpdates.queue" 
                                channel="pricehub.fixtures.priceUpdates.subpub"
                                message-converter="jsonMessageConverter"/>
    
    <int:publish-subscribe-channel id="pricehub.fixtures.priceUpdates.subpub" />
    <int:bridge input-channel="pricehub.fixtures.priceUpdates.subpub" 
        output-channel="pricehub.fixtures.priceUpdates.channel" />
    
    <int:channel id="pricehub.fixtures.priceUpdates.channel">
        <int:queue  />
    </int:channel>
    
    <int:service-activator ref="updatePriceAction" 
         method="updatePrices" 
         input-channel="pricehub.instruments.priceUpdates.channel">
        <int:poller fixed-delay="50" time-unit="MILLISECONDS" task-executor="taskExecutor" />
    </int:service-activator>
    
    <task:executor id="taskExecutor" pool-size="5-50" keep-alive="120" queue-capacity="500"/>
    

    This seems like a LOT of code to achieve a fairly trivial task - so if anyone has better solutions, or suggestions for improvements, I'd love to see them.

    0 讨论(0)
提交回复
热议问题