我们有一个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数据库更有意义。
如果所有服务器执行轮询步骤然后一个服务器锁定以实际处理记录,那就没关系了,如果这更容易实现的话。
答案 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
这样的东西,或者你可以使用任何分布式锁机制。