简体   繁体   English

如何在Spring Integration中处理繁重的消息加载?

[英]How to handle heavy message load in Spring Integration?

External module sends thousands of messages to the message broker. 外部模块将数千条消息发送到消息代理。 Each message has a TimeToLive property equal to 5 secs. 每条消息的TimeToLive属性等于5秒。 Another module should consume and process ALL the messages. 另一个模块应该使用和处理所有消息。

From Spring Integration documentation I found that Staged Event-driven architecture (consumers) respond better to significant spikes in the load. 从Spring Integration文档中我发现,分阶段事件驱动架构(消费者)对负载中的显着峰值做出了更好的响应。

My current implementation uses EDA (even Driven Architecture), eg 我目前的实现使用EDA(甚至驱动架构),例如

<si:channel id="inputChannel"/>

<!-- get messages from PRESENCE_ENGINE queue -->    
<int-jms:message-driven-channel-adapter id="messageDrivenAdapter" 
    channel="inputChannel" destination="sso" connection-factory="connectionFactory"  
    max-concurrent-consumers="1" auto-startup="true" acknowledge="transacted" extract-payload="true"/>

<si:service-activator id ="activatorClient" input-channel="inputChannel" ref="messageService" method="processMessage"/> 

<bean id="messageService" class="com.my.messaging.MessageService"/>

<bean id="sso" 
    class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="SSO" />
</bean> 

Obviously by heavy load,eg incoming thousands of messages, processMessage() can take longer than 5 secs. 显然,由于负载很重,例如传入数千条消息,processMessage()可能需要超过5秒。 and the MessageService may not handle all the messages. 并且MessageService可能无法处理所有消息。

My ideas are following: 我的想法如下:

  1. Modify processMessage() so that the message instead of being processed is only stored in MongoDB. 修改processMessage(),以便消息而不是被处理的消息只存储在MongoDB中。 Then I could process the messages in a separate task independently. 然后我可以独立处理单独任务中的消息。 In such a scenario MongoDB would serve as a CACHE. 在这种情况下,MongoDB将充当CACHE。

  2. Use a large number of consumers (SEDA model). 使用大量消费者(SEDA模型)。 The inputChannel is a direct channel. inputChannel是直接通道。

  3. Process the messages asynchronously, eg inputChannel is a queue channel and the messages are processed asynchronously. 异步处理消息,例如inputChannel是队列通道,并且异步处理消息。

Before making the decision I would like to ask you which scenario is more effective. 在做出决定之前,我想问你哪种情况更有效。 Perhaps Scenarios 2) and 3) provides a mechanism for meeting my requirement that ALL messages should be processed, even by heavy loads. 也许方案2)和3)提供了一种机制来满足我的要求,即所有消息都应该被处理,即使是重负载也是如此。

EDIT: 编辑:

I already implemented scenario 2 where I keep sending 1000 messages per second. 我已经实现了方案2,我每秒发送1000条消息。 This is the statistics how many messages were missing with varying parameters: 这是统计有多少消息丢失的参数:

max-concurrent-consumers ; 最大并发消费者; TimeToLive=5secs.; 传输TimeToLive = 5secs .; Idle-consumer-limit; 空闲消费限制; # of sent messages; 发送的消息数量; # of received messages 收到的消息数量

 10 ; Yes ; 1   ; 1001 ; 297
100 ; Yes ; 1   ; 1001 ; 861
150 ; Yes ; 1   ; 1001 ; 859
300 ; Yes ; 1   ; 1001 ; 861
300 ; No  ; 1   ; 1001 ; 860
300 ; No  ; 100 ; 1001 ; 1014
300 ; No  ; 50  ; 1001 ; 1011

It seems idle-consumer-limit creates consumers more aggresively than max-concurrent consumers. 似乎闲置 - 消费者限制比最大并发消费者更具侵略性地创造消费者。 Is this is a good approach to use idle-consumer-limit in such a scenario? 这是在这种情况下使用idle-consumer-limit的好方法吗?

This is my config files for sender/consumer: 这是发件人/消费者的配置文件:

<!-- SENDER  
Keep Alive Sender sends messages to backup server -->    

<si:channel id="sendToChannel"/>
<si:channel id="presChannel"/>

<si:inbound-channel-adapter id="senderEntity" channel="sendToChannel" method="sendMessage"> 
    <bean class="com.ucware.ucpo.sso.cache.CacheSender"/>
    <si:poller fixed-rate="${sender.sendinterval}"></si:poller>
</si:inbound-channel-adapter>    

<si:router id="messageRouter" method="routeMessage" input-channel="sendToChannel">
    <bean class="com.ucware.ucpo.sso.messaging.MessageRouter"/>
</si:router>

<!-- Subscriber to a channel dispatcher, Send messages to JMS -->
<int-jms:outbound-channel-adapter  explicit-qos-enabled="${jms.qos.enabled}" time-to-live="${jms.message.lifetime}" 
    channel="presChannel" connection-factory="connectionFactory" destination="pres" extract-payload="false"/>

<bean id="pres" 
    class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="PRES" />
</bean>


<!-- RECEIVER -->

<si:channel id="receiveChannel"/>

<!-- get messages from PRES queue -->    
<int-jms:message-driven-channel-adapter id="messageDrivenAdapter" 
    channel="receiveChannel" destination="presence" connection-factory="connectionFactory"  idle-consumer-limit="50" 
    max-concurrent-consumers="300" auto-startup="true" acknowledge="transacted" extract-payload="true"/>

<si:service-activator id ="activatorClient" input-channel="receiveChannel" ref="messageService" method="processMessage"/> 


<bean id="messageService" class="com.cache.MessageService"/>

First of all you can try to play with max-concurrent-consumers property. 首先,您可以尝试使用max-concurrent-consumers属性。 As you see, in your case 1 is really not enough. 如你所见,在你的情况下1真的不够。 You should investigate why your MessageService is so slowly. 您应该调查您的MessageService为什么这么慢。 Any other cases looks like overhead, because JMS is already persistent and have async nature - queue-based. 任何其他情况看起来都是开销,因为JMS已经是持久的并且具有异步性质 - 基于队列。 If it doesn't help, so use <queue> channel with presistence MessageStore , eg MongoDB 如果它没有帮助,那么使用<queue>通道与presstence MessageStore ,例如MongoDB

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何接收/处理发送给运行Spring Boot / Integration的用户的XMPP消息 - How to receive/handle an XMPP message send to a user running Spring Boot / Integration Spring集成:从JMS中读取-&gt;处理消息-&gt;在DB中持久 - Spring Integration : Read from JMS -> Handle message -> Persist in DB Spring Integration如何处理EmptyResultDataAccessException? - How do you handle EmptyResultDataAccessException with Spring Integration? Spring Integration-如何处理LoggingHandler的异常 - Spring Integration - How to handle exception from LoggingHandler 如何处理 spring 集成中的嵌套事务异常 - How to handle nested transaction exception in spring integration 如何在Spring Integration的集成测试中处理errorChannel事件? - How do I handle errorChannel events in a integration test for Spring Integration? 如何使用 Spring Integration 发送 gcm xmpp 消息? - How to send a gcm xmpp message with Spring Integration? 如何在Spring Integration中重新启动消息使用者? - How to restart the message consumer in Spring Integration? 如何将Spring Integration消息标头保存到数据库中 - How to save spring integration message header into database 弹簧缓存不能在重负载下工作? - spring caching not working under heavy load?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM