0

我正在使用 spring 调度程序来调度作业。它在本地运行良好,但在服务器上它为同一个实例运行多次。

从服务器登录

20 Mar 2014 09:00:00 [pool-3-thread-1] INFO  com.yourkey.jobs.GetDeviceStatusJob  - *** No Lost Devices ***
20 Mar 2014 09:00:00 [pool-5-thread-1] INFO  com.yourkey.jobs.GetDeviceStatusJob  - *** No Lost Devices ***
20 Mar 2014 09:00:00 [pool-4-thread-1] INFO  com.yourkey.jobs.GetDeviceStatusJob  - *** No Lost Devices ***

应用程序上下文.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.1.xsd
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    -------------------------------------
    -------------------------------------

    <task:annotation-driven />
    <bean id="syncBrandOffersJob" class="com.yourkey.jobs.SyncBrandOffersJob"></bean>
    <bean id="getDeviceStatusJob" class="com.yourkey.jobs.GetDeviceStatusJob"></bean>


</beans>

GetDeviceStatusJob.java

@Service
public class GetDeviceStatusJob {

private static final Logger logger = Logger
        .getLogger(GetDeviceStatusJob.class);

@Autowired
private DeviceService deviceService;

public DeviceService getDeviceService() {
    return deviceService;
}

public void setDeviceService(DeviceService deviceService) {
    this.deviceService = deviceService;
}

@Scheduled(cron = "0 0/10 * * * ?")
public void getLostDeviceInfo() {
    List<Device> deviceList = deviceService.getAllLostDevices();
    if (deviceList != null && !deviceList.isEmpty()) {
        for (Device device : deviceList) {
            String gcmRegistrationId = device.getGcmRegistrationId();
            if (gcmRegistrationId != null) {
                String status = null;
                if (device.isStatus()) {
                    status = "LOST";
                } else {
                    status = "Active";
                }
                String message = device.getMessage();

                String jsonString = "{\"status\":\"" + status
                        + "\",\"message\":\"" + message
                        + "\",\"registration_ids\" : [\""
                        + gcmRegistrationId + "\"]}";
                System.out.println(jsonString);
                NetClientUtil.httpGcmPostClient(jsonString,
                        "getLostDeviceInfo");
            }else{
                logger.info("**** gcmRegistrationId not present for device" + device.getId());
            }
        }
    }else{
        logger.info("*** No Lost Devices ***");
    }
}
}
4

1 回答 1

2

正如@MaciejWalkowiak 所说,正如手册所说,

确保您没有在运行时初始化同一 @Scheduled 注释类的多个实例,除非您确实想为每个此类实例安排回调。与此相关,请确保不要在使用 @Scheduled 注释并在容器中注册为常规 Spring bean 的 bean 类上使用 @Configurable:否则,您将获得双重初始化,一次通过容器,一次通过 @Configurable 方面,每个@Scheduled 方法被调用两次的结果。

登录this您的工作。如果它是同一个实例,则调度会以某种方式被错误地触发。如果没有,您将实例化计划的课程三次。

更新:由于您说它是特定于环境的,因此我对此进行了更多考虑,并注意到线程池名称不同,但它们都是各自池中的线程 1。这意味着您有多个ThreadPoolTaskExecutors. 您是否以某种方式创建多个容器?

于 2014-03-20T09:57:46.807 回答