集群环境下,机器会有多个,需要执行某个或者多个机器执行后台任务,否则可能会一个数据多个机器同时处理导致bug。这在实际工作中很常见。最近项目中也有类似需求,下面是一种实现方式,供大家参考。
使用 @Conditional 注解,判断是本机ip才加载对应的任务的service,非配置的ip的机器则不会加载到spring容器。
IP判断类
package cn.xiaowenjie.iptask;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.net.InetAddress;
/**
* 判断是否为本机ip
*
* @author 晓风轻
*/
@Slf4j
public class IPCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String runTaskIP = conditionContext.getEnvironment().getProperty("run.task.ip");
String localIP = this.getLocalIP();
log.info("local ip: {} , run Task IP: {}" ,localIP , runTaskIP);
return runTaskIP.equals(localIP);
}
@SneakyThrows
public String getLocalIP(){
InetAddress address = InetAddress.getLocalHost();
return address.getHostAddress();
}
}
后台任务类
package cn.xiaowenjie.iptask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Conditional;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
/**
* 后台定时任务
*
* @author 晓风轻
*/
@Service
@Slf4j
@Conditional(IPCondition.class)
public class BackService {
@PostConstruct
public void init(){
log.info("i run task...");
}
@Scheduled(cron = "0/10 * * * * *")
public void scheduleTask(){
log.info("task running....");
}
}
实际效果
[ main] cn.xiaowenjie.iptask.IPCondition : local ip: 192.168.1.101 , run Task IP: 192.168.1.101
[ main] cn.xiaowenjie.iptask.IPCondition : local ip: 192.168.1.101 , run Task IP: 192.168.1.101
[ main] cn.xiaowenjie.iptask.IPCondition : local ip: 192.168.1.101 , run Task IP: 192.168.1.101
[ main] cn.xiaowenjie.iptask.BackService : i run task...
[ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
[ main] cn.xiaowenjie.iptask.IptaskApplication : Started IptaskApplication in 1.364 seconds (JVM running for 2.098)
[ scheduling-1] cn.xiaowenjie.iptask.BackService : task running....
[ scheduling-1] cn.xiaowenjie.iptask.BackService : task running....
[ scheduling-1] cn.xiaowenjie.iptask.BackService : task running....
[ scheduling-1] cn.xiaowenjie.iptask.BackService : task running....