我有一个使用jdbc:inbound-channel-adapter
从数据库读取数据的配置。配置:
<int-jdbc:inbound-channel-adapter query="SELECT * FROM requests WHERE processed_status = '' OR processed_status IS NULL LIMIT 5" channel="requestsJdbcChannel"
data-source="dataSource" update="UPDATE requests SET processed_status = 'INPROGRESS', date_processed = NOW() WHERE id IN (:id)" >
<int:poller fixed-rate="30000" />
</int-jdbc:inbound-channel-adapter>
<int:splitter input-channel="requestsJdbcChannel" output-channel="requestsQueueChannel"/>
<int:channel id="requestsQueueChannel">
<int:queue capacity="1000"/>
</int:channel>
<int:chain id="requestsChain" input-channel="requestsQueueChannel" output-channel="requestsApiChannel">
<int:poller max-messages-per-poll="1" fixed-rate="1000" />
.
.
</int:chain>
在上面的配置中,我定义了jdbc轮询器,fixed-rate
为30秒。当有直接通道而不是requestsQueueChannel
时,select查询只获得5行(因为我使用限制select查询中的行)并等待另一个30秒进行下一次轮询。
但是,在我使用队列引入requestsQueueChannel
并在requestsChain
内添加了轮询后,jdbc-inbound
并未按预期工作。它不会等待另一个30秒进行下一轮调查。有时它连续两次(在一秒内)轮询数据库,好像有2个线程正在运行并从DB获取两组行。但是,除了上面提到的那些之外,没有异步切换。
我的理解是,即使有requestsQueueChannel
,一旦执行了select查询,它应该等待另外30秒来轮询数据库。有什么我想念的吗?我只是想了解这种配置的行为。
答案 0 :(得分:0)
使用DirectChannel
时,下一轮投票在当前投票结束前不予考虑。
使用QueueChannel
(或任务执行程序)时,轮询器可以再次运行。
默认情况下,入站适配器的max-messages-per-poll
设置为1,因此您的配置应按预期工作。你能在某处发布DEBUG日志吗?
答案 1 :(得分:0)
Spring集成轮询器激活两次的问题,好像它们是2个线程一样,这是我遇到的基本相同的问题,使用文件系统轮询器:
How to prevent duplicate Spring Integration service activations when polling directory
显然这是一种相对常见的错误配置,其中Spring root和servlet上下文都加载了Spring Integration配置。因此,确实存在两个线程,并且可以看到轮询器在其轮询周期内激活两次。通常在彼此的几秒钟内,因为每个都将在其上下文加载时开始。
我确保仅在单个上下文中加载Spring Integration配置的方法是构建项目包以确保分离。
首先定义一个只接受“web”包下的类的Web配置。
@Configuration
@ComponentScan(basePackages = { "com.myapp.web" })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
创建单独的根配置类以加载bean,例如服务和存储库,这些bean不属于servlet上下文。其中一个应该加载Spring Integration配置。即:
@Configuration
@ComponentScan(basePackages = { "com.myapp.eip" })
@ImportResource(value = { "classpath:META-INF/spring/integration-context.xml" })
public class EipConfig {
}
配置中需要花费一些时间才能解决的另一个因素是我的servlet过滤器和Web安全配置需要位于根上下文而不是servlet上下文中。