#java #spring-mvc #cron #quartz-scheduler
#java #spring-mvc #cron #quartz-планировщик
Вопрос:
В моем проекте Spring есть планировщик Quartz Cron, который выполняет методы, объявленные в MyCron.java файл. В quartz.xml файл, я настроил компоненты в этом формате:
<beans>
<bean id="wakeUsers" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="mycron" />
<property name="targetMethod" value="wakeUsers" />
</bean>
<bean id="wakeUsersCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="wakeUsers" />
<property name="timeZone" ref="timeZone" />
<property name="cronExpression" value="0 0/5 * * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="wakeUsers" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="wakeUsersCronTrigger" />
</list>
</property>
</bean>
</beans>
Он работает нормально. Вопрос в том, что в настоящее время я использую 3 машины в производстве, и cron запускается на всех трех
машины сразу. Я хочу запустить cron в соответствии с именем компьютера. Когда имя конкретной машины совпадает с именем в
свойство, cron должен выполняться, иначе нет.
Предпочтительно с помощью Java-кода, я хотел бы сопоставить мое свойство, хранящееся в DB, с именем моей машины, а затем выполнить мой метод.
В настоящее время я реализовал следующее:
public boolean testRun(){
try {
InetAddress ip = InetAddress.getLocalHost();
String hostName = ip.getHostName();
if(nodeName.equalsIgnoreCase(hostName)){
return true;
}
} catch (UnknownHostException e) {
logger.error("Error: Unknown Host");
}
return false;
}
public void wakeUsers() throws Exception{
if (testRun()) {
myService.wakeUsers();
}
}
Любая помощь будет оценена.
Ответ №1:
Когда я столкнулся с этим, я создал MethodInvokingJobOnSpecifiedMachine
который был компонентом, который запускался на всех машинах, но ничего не делал, если имя машины не совпадало.
Тогда детали задания будут:
<property name="jobDetail">
<bean class="foo.bar.MethodInvokingJobOnSpecifiedMachine">
<property name="machineName" value="DatabaseServer"/>
<property name="targetObject" ref="mycron" />
<property name="targetMethod" value="wakeUsers" />
</bean>
</property>
Боюсь, у меня больше нет реализации.
Комментарии:
1. Это может сработать. Но есть что-то еще, что я ищу.
Ответ №2:
Мне удалось найти решение, в котором я использовал Spring AOP для перехвата метода, вызываемого cron.
Я создал класс с именем BaseCron, который реализует интерфейс MethodBeforeAdvice пакета Spring AOP. Я переопределил метод ранее и написал там свою логику, которая должна была выполняться перед каждым вызовом метода в классе MyCrons.
Затем я создал прокси-компонент в файле конфигурации Spring как:
<bean id="cronsProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="mycrons" />
<property name="interceptorNames">
<list>
<value>baseCronBean</value>
</list>
</property>
</bean>
Поэтому, прежде чем был вызван какой-либо метод в моих микронах, он был перехвачен методом before, присутствующим в моем классе BaseCron, где я проверил имя машины свойств, на которой будет выполняться cron.
Приветствия!