Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring集成中最好地实现DynamicPoller_Java_Spring_Spring Integration - Fatal编程技术网

Java 如何在Spring集成中最好地实现DynamicPoller

Java 如何在Spring集成中最好地实现DynamicPoller,java,spring,spring-integration,Java,Spring,Spring Integration,我有一个接收大消息的流(在RDBMS表中),所以我不能在给定时间处理太多这些消息。因此,我使用限制处理,并且使用一些队列,其容量设置为。我知道多个线程/事务将参与这个流,对于用例来说,这是可以接受的 轮询DB的查询需要一些时间才能运行,因此我不希望运行的次数超过我需要的次数。此外,该流接收的消息往往以“突发”的形式出现,这意味着它可能会收到1000条消息,但在一个小时内不会收到任何消息 我想做的是使用一个动态轮询器,它将不经常轮询(因为如上所述,查询运行成本很高),除非我看到我收到了大量消息,在

我有一个接收大消息的流(在RDBMS表中),所以我不能在给定时间处理太多这些消息。因此,我使用
限制处理,并且使用一些
队列
,其
容量设置为
。我知道多个线程/事务将参与这个流,对于用例来说,这是可以接受的

轮询DB的查询需要一些时间才能运行,因此我不希望运行的次数超过我需要的次数。此外,该流接收的消息往往以“突发”的形式出现,这意味着它可能会收到1000条消息,但在一个小时内不会收到任何消息

我想做的是使用一个
动态轮询器
,它将不经常轮询(因为如上所述,查询运行成本很高),除非我看到我收到了大量消息,在这种情况下,我希望非常频繁地轮询,直到处理完所有消息。例如,如果我有
,并且我知道轮询器刚刚读取了100条消息,那么RDBMS中有更多需要处理的消息的可能性很大,我应该在处理完成后立即再次轮询

我知道Spring没有提供一种方法来修改
触发器
,使其在本质上具有动态性,并且已经研究了Spring集成参考“ 在
动态轮询器
示例项目:
这是一个开始,但我确实需要
轮询器根据当前负载更改频率。
关于这一点,我可能不太正确,但我认为Gary在关于“”的演讲中提到的类似内容可能会很有趣。
无论如何,编写一个类来更改
轮询器的频率似乎不是什么大问题。更具挑战性的是,如何知道何时发生了轮询,但由于没有任何结果发布到输出通道,因此没有结果

我考虑过的一些选择:

  • 连接到调用
    的轮询器的频道。Service activator检查消息的数量,并调整
    DynamicPeriodicTrigger上
    轮询器的
    时段

    问题是,若并没有收到任何消息,这将永远不会被调用,所以一旦我调整轮询频率,轮询周期将保持不确定

  • 与#1相同,但向
    DynamicPeriodicTrigger
    添加逻辑,该逻辑将在下一次触发发生后或在特定时间段后将
    周期
    恢复为
    初始延迟

  • 元素中的
    元素与
    MethodInterceptor
    实现一起使用。
    类似于Artem在本文中的建议。 虽然这允许我进入
    receive
    方法的前面,但它不允许我访问
    receive
    方法的结果(这将为我提供检索到的消息数量)。请注意,Gary在本文中提到的内容似乎证实了这一点

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

    建议轮询器更简单,因为我们建议整个流程。如“7.1.4命名空间支持”小节“AOP建议链”中所述,您只需通过实现MethodInterceptor接口创建建议

    有关非常简单的建议,请参见
    SourcePollingChannelAdapterFactoryBeanTests.testAdviceChain()

    代码:
    添加(新方法拦截器(){

  • 公共对象调用(MethodInvocation调用)抛出可丢弃的{

    adviceappliced.set(true);

    返回调用。继续();

    }

    });

    这只是用来断言通知被正确调用;真正的通知将在调用之前和/或之后添加代码。继续()

    实际上,此建议建议所有方法,但只有一个(
    Callable.call()

  • 返回
  • 通知后创建一个
    ,该通知带有一个查找
    Message receive()
    方法的切入点

  • 克隆
    JdbcPollingChannelAdapter
    并在新类中添加我的挂钩

  • 也许加里在这方面的建议会有用,但“要点”链接不再有效

  • 更新:
    我最终实现的选项是在returningadvice
    之后使用类似以下内容的

    原始代码:

    <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>
    
    
    
    新代码:

    <bean id="jdbcDynamicTrigger" class="DynamicPeriodicTrigger">
        <constructor-arg name="period" value="20000" />
    </bean> 
    <bean id="jdbcPollerMetaData" class="org.springframework.integration.scheduling.PollerMetadata">
        <property name="maxMessagesPerPoll" value="1000"/>
        <property name="trigger" ref="jdbcDynamicTrigger"/>
    </bean>
    <bean id="pollMoreFrequentlyForHighVolumePollingStrategy" class="springintegration.scheduling.PollMoreFrequentlyForHighVolumePollingStrategy">
        <property name="newPeriod" value="1"/>
        <property name="adjustmentThreshold" value="100"/>
        <property name="pollerMetadata" ref="jdbcPollerMetaData"/>
    </bean> 
    <aop:config>
        <aop:aspect ref="pollMoreFrequentlyForHighVolumePollingStrategy" >
            <aop:after-returning pointcut="bean(jdbcInAdapterBean) and execution(* *.receive(..))" method="afterPoll" returning="returnValue"/>
        </aop:aspect>   
    </aop:config>   
    <bean id="jdbcInAdapterBean" class="org.springframework.integration.jdbc.JdbcPollingChannelAdapter">
        <constructor-arg ref="myDataSource" />
        <constructor-arg value="SELECT column1, column2 from tableA" />
        <property name="maxRowsPerPoll" value="100" />
    </bean> 
    <int:inbound-channel-adapter id="jdbcInAdapter" ref="jdbcInAdapterBean" 
        channel="inputChannel"
        auto-startup="false">
        <int:poller ref="jdbcPollerMetaData" />
    </int:inbound-channel-adapter>
    
    
    


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

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


    但是,我不确定您上面所说的“……但是”gist“链接不再有效……”。它对我来说很好……但是让我们在JIRA中讨论。

    是的,您是对的,gist链接仍然有效。在打开此问题时,它似乎被我使用的浏览器内部阻止。