如何最好地在Spring Integration中实现DynamicPoller

时间:2015-02-06 15:37:24

标签: java spring spring-integration

我有一个接收大量消息的流(落在RDBMS表中),因此我无法在给定时间处理过多这些消息。因此,我使用<int:poller max-messages-per-poll="" />限制处理,并使用queues设置capacity设置<int:queue capacity="">。我知道多个线程/事务将参与此流程,对于用例,这是可以接受的。

轮询数据库的查询需要一些时间才能运行,因此我不想比我需要的更频繁地运行它。此外,此流所接收的消息往往会在&#34;突发中出现,这意味着它可能会获得1000条消息,然后一小时内无法获取。

我想要做的是使用不经常轮询的dynamic-poller(因为注意查询运行成本很高),除非我看到我收到了一连串消息,在这种情况下我想要非常频繁地轮询,直到处理完所有消息。例如,如果我有<int:poller max-messages-per-poll="100" />并且我知道轮询器只读取了100条消息,那么很可能RDBMS中有更多消息需要处理,我应该在处理完成后立即再次轮询。

我知道Spring并没有提供修改trigger以使其具有动态性的方法,并且已经看过Spring Integration Ref“7.1.5 Change Polling Rate at Runtime&#34; 在dynamic-poller示例项目:Dynamic Poller
这是一个开始但我真的需要poller根据当前负载更改频率。
我可能在这方面不正确,但我想也许加里提到这样的事情会在他关于&#34; Implementing High-Availability Architectures with Spring Integration &#34;的演讲中实施。 无论如何,写一个类来改变poller频率似乎并不重要。更具挑战性的是如何知道何时发生了没有结果的投票,因为没有任何结果发布到输出通道。

我考虑过的一些选项:

  1. <int:wire-tap channel="" />附加到调用poller的{​​{1}}频道。服务激活器会检查邮件数量,并在<int:service-activator>上调整poller period。 问题是,如果没有收到任何消息,这将永远不会被调用,所以一旦我调整为更频繁地轮询轮询周期将无限期。

  2. 与#1相同,但向DynamicPeriodicTrigger添加逻辑,该逻辑会在下一次触发后或在一段时间后将DynamicPeriodicTrigger恢复为period

  3. initialDelay元素中使用<int:advice-chain>元素并执行<int:poller>
    与Artem在此link中的建议类似。 虽然这允许我放在MethodInterceptor方法的前面,但它不允许我访问receive方法的结果(这会给我检索的消息数)。请注意,这似乎是由加里提到的link提到的。

      

    请求处理程序通知链是一种特殊情况;我们必须注意只建议内部端点方法,而不是任何下游处理(在输出通道上)。

         

    向投票人提供建议比较简单,因为我们会建议整个流程。如第34节中所述; 7.1.4命名空间支持&#34;小部分&#34; AOP建议链&#34;,您只需通过实现MethodInterceptor接口来创建建议。

         

    请参阅receive以获取非常简单的建议......

         

    代码:
      SourcePollingChannelAdapterFactoryBeanTests.testAdviceChain()
      adviceChain.add(new MethodInterceptor() {
      public Object invoke(MethodInvocation invocation) throws Throwable {
      adviceApplied.set(true);
      return invocation.proceed();
      }
      这只是用于断言建议被正确调用;真正的建议会在invocation.proceed()之前和/或之后添加代码。

         

    实际上,这个建议建议所有方法,但只有一个,(});)。

  4. 使用查找Callable.call()方法的切入点创建AfterReturning个建议。

  5. 克隆Message<T> receive()并在新课程中添加我的挂钩。

  6. 也许加里对这个link的建议是有用的,但是&#34; gist&#34;链接不再有效。

  7. 更新:
    我最终实现的选项是使用类似于以下内容的JdbcPollingChannelAdapter 原始代码:

    AfterReturningAdvice

    新代码:

    <int-jdbc:inbound-channel-adapter id="jdbcInAdapter" 
        channel="inputChannel" data-source="myDataSource"
        query="SELECT column1, column2 from tableA"
        max-rows-per-poll="100">
        <int:poller fixed-delay="10000"/>
    </int-jdbc:inbound-channel-adapter>
    

    我已经对此做了一些研究,并认为Spring Integration可能会为查询者提供一些钩子,以便开发人员可以更好地定制它们。
    有关详细信息,请参阅https://jira.spring.io/browse/INT-3633

    如果JIRA没有得到实现,并且有人对我实现的代码感兴趣,请在此添加注释,我将在github或gist上提供代码。

1 个答案:

答案 0 :(得分:1)

感谢您开启JIRA问题;我们应该讨论那里的功能,因为堆栈溢出不适合扩展对话。

但是,我不确定你的意思是“......但是”主旨“链接不再有效......”。它对我来说很好...... https://gist.github.com/garyrussell/5374267但是让我们在JIRA中讨论。