我想了解IScheduledExecutorService的hazelcast方法之间的区别,以防止重复的任务。 我有两个带有HazelcastInstance的Java应用程序。我分别有两个HazelcastInstances(服务器)的hazelcast集群。 我使用IMap并希望每隔午夜重置AtomicLong。
config.getScheduledExecutorConfig("my scheduler")
.setPoolSize(16)
.setCapacity(100)
.setDurability(1);
class DelayedResetTask implements Runnable, HazelcastInstanceAware, Serializable {
static final long serialVersionUID = -7588380448693010399L;
private transient HazelcastInstance client;
@Override
public void run() {
final IMap<Long, AtomicLong> map = client.getMap(HazelcastConfiguration.mapName);
final ILogger logger = client.getLoggingService().getLogger(HazelcastInstance.class);
logger.info("Show data in cache before reset: " + map.entrySet());
map.keySet().forEach(key -> map.put(key, new AtomicLong(0)));
logger.info("Data was reseted: " + map.entrySet());
}
@Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.client = hazelcastInstance; }
}
private void resetAtMidnight() {
final Long midnight = LocalDateTime.now().until(LocalDate.now().plusDays(1).atStartOfDay(), ChronoUnit.MINUTES);
executor.scheduleAtFixedRate(new DelayedResetTask(), midnight, TimeUnit.DAYS.toMinutes(1), TimeUnit.MINUTES);
}
我不想并行地在每个实例上执行此任务。阅读文档documentation后,我不明白如何在一个步骤中执行两个服务器中的重置(没有重复任务,一次不在两个服务器上执行)。
我可以使用哪种方法处理我的任务scheduleOnAllMembersAtFixedRate
或scheduleAtFixedRate
或scheduleOnMembersAtFixedRate
。
如何在群集中的应用程序上运行相同的IScheduledExecutorService时防止重复任务?
答案 0 :(得分:1)
您需要在群集中仅运行一次代码,因为您重置的地图可以从任何成员访问。两个成员都访问同一个映射实例,只有条目保存在不同的成员中。您可以使用scheduleAtFixedRate
运行一次。
此外,您无需调用IMap#keySet().forEach()
来遍历地图中的所有条目。相反,您可以使用EntryProcessor
,如下所示:
public static class DelayedResetTask implements Runnable, HazelcastInstanceAware, Serializable {
static final long serialVersionUID = -7588380448693010399L;
private transient HazelcastInstance client;
@Override
public void run() {
final IMap<Long, AtomicLong> map = client.getMap(HazelcastConfiguration.mapName);
final ILogger logger = client.getLoggingService().getLogger(HazelcastInstance.class);
logger.info("Show data in cache before reset: " + map.entrySet());
map.executeOnEntries(new AbstractEntryProcessor() {
@Override
public Object process(Map.Entry entry) {
entry.setValue(new AtomicLong(0));
return null;
}
});
logger.info("Data was reseted: " + map.entrySet());
}
@Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.client = hazelcastInstance; }