Spring Integration在多个服务器上轮询入站通道适配器

时间:2015-01-14 15:48:58

标签: java spring oracle mongodb spring-integration

我们有一个Spring Integration应用程序正在轮询mongodb:inbound-channel-adapter,如此:

<int-mongodb:inbound-channel-adapter channel="n2s.mongoResults"
                                     collection-name="entities"
                                     query="{_id: {$regex: 'mpl/objectives'}})">
    <!-- Run every 15 minutes -->
    <int:poller fixed-rate="900000"/>
</int-mongodb:inbound-channel-adapter>

一切正常。但是,此应用程序已部署到群集,因此多个服务器正在运行相同的轮询器。我们想协调这些服务器,只有一个服务器运行管道。

当然,服务器彼此不了解,所以我们可能需要通过数据库中的锁定机制来协调它们。有关如何实现这一目标的任何建议吗?

说明:

我们可以在此工作流程中访问MongoDB数据库和Oracle数据库。从工作流的角度来看,锁定Oracle数据库更有意义。

如果所有服务器执行轮询步骤然后一个服务器锁定以实际处理记录,那就没关系了,如果这更容易实现的话。

2 个答案:

答案 0 :(得分:0)

  

有关如何实现这一目标的任何建议吗?

您可以使用像Zookeeper这样的分布式锁定工具。另一种方法是从简单的固定触发器更改为Quartz等调度框架,这将确保作业仅在单个节点上执行。

  

如果所有服务器执行轮询步骤然后执行一个服务器,那就没问题了   锁定实际处理记录,如果这更容易实现。

是的,这就是我要做的。我认为这是迄今为止最简单的方法。请参阅this post for details on how to do locking with Oracle

答案 1 :(得分:0)

有几种选择,包括:

设置auto-startup="false"并使用一些管理工具来监控服务器并确保只有一个适配器正在运行(您可以使用control-bus或JMX来启动/停止适配器。

在SpringXD容器中运行应用程序;设置源的模块计数(包含mongo适配器),XD管理员将确保实例正在运行。它使用Zookeeper来管理状态。

使用分布式锁定以确保只有一个实例处理消息。 Spring Integration本身带有RedisLockRegistry这样的东西,或者你可以使用任何分布式锁机制。