spring-boot定时任务执行多线程
程序员文章站
2022-05-01 17:16:13
...
1.定时任务配置类
主要实现了SchedulingConfigurer接口,要重写configureTasks方法
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
public static final Logger LOGGER = LoggerFactory.getLogger(ScheduleConfig.class);
/**
* Redis
*/
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// 心跳检测定时模块
taskRegistrar.addTriggerTask(new CheckHeartRunnable(stringRedisTemplate, deviceService), new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
//Constants.deviceAckCheckCron = "0/5 * * * * ?"
CronTrigger trigger = new CronTrigger(Constants.deviceHeartCheckCron);
Date nextExec = trigger.nextExecutionTime(triggerContext);
return nextExec;
}
});
}
2.任务类:执行设备心跳检测
这个类实现了Runnable接口,执行定时任务时,就开了一个线程.
package com.polycis.ns2g.domain.schedule.runnable;
import com.polycis.ns2g.comment.MapConfigurator;
import com.polycis.ns2g.config.PropertyConf;
import com.polycis.ns2g.domain.entity.DataEntity;
import com.polycis.ns2g.domain.entity.DeviceEntity;
import com.polycis.ns2g.domain.service.IDeviceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.Date;
import java.util.Map;
import static com.polycis.ns2g.comment.Constants.deviceTimeOut;
import static com.polycis.ns2g.comment.Constants.getaWayTimeOut;
import static com.polycis.ns2g.comment.MapConfigurator.*;
import static com.polycis.ns2g.comment.MapConfigurator.CHANNEL_ENTITY_MAP;
import static com.polycis.ns2g.comment.MapConfigurator.DEVICE_HEART_DATA;
public class CheckHeartRunnable implements Runnable {
public static final Logger LOGGER = LoggerFactory.getLogger(CheckHeartRunnable.class);
private StringRedisTemplate stringRedisTemplate;
private IDeviceService deviceService;
public CheckHeartRunnable(StringRedisTemplate stringRedisTemplate, IDeviceService deviceService){
this.stringRedisTemplate = stringRedisTemplate;
this.deviceService = deviceService;
}
/**
* 该方法用来检测内存中心跳停止了的设备,并清除设备对应的数据信息
*/
@Override
public void run() {
// LOGGER.info("================= 设备心跳检测功能定时模块启动 =================");
// 定时检测硬件心跳数据
// 检测当前系统中是否存在超时未上报心跳的设备
checkHeart(DEVICE_HEART_DATA, deviceTimeOut);
// 检测当前系统中是否存在超时未上报心跳的网关
checkHeart(GETAWAY_HEART_DATA, getaWayTimeOut);
}
private void checkHeart(Map<String, Date> heartDate, Integer devTimeOut){
long now = System.currentTimeMillis();
long time;
Integer pattern;
Integer timeOut;
for (Map.Entry<String, Date> entry : heartDate.entrySet()){
pattern = MapConfigurator.DEVICE_FOR_PATTERN.get(entry.getKey());
if (pattern == null){
String patString = stringRedisTemplate.opsForValue().get(entry.getKey() +
PropertyConf.config.getProperty("redis.device.pattern.suffix"));
if (patString == null) {
time = now - (devTimeOut * 1000);
}else {
pattern = Integer.valueOf(patString);
timeOut = MapConfigurator.CONFIG_FOR_PATTERN.get(pattern);
if (timeOut == null){
time = now - (devTimeOut * 1000);
}else{
time = now - (timeOut * 1000);
System.out.println("设备属于模式:" + pattern + ", 超时时间为:" + timeOut + "秒");
}
}
}else{
timeOut = MapConfigurator.CONFIG_FOR_PATTERN.get(pattern);
if (timeOut == null){
time = now - (devTimeOut * 1000);
}else{
time = now - (timeOut * 1000);
System.out.println("设备属于模式:" + pattern + ", 超时时间为:" + timeOut + "秒");
}
}
if (entry.getValue() != null && entry.getValue().getTime() < time){
// 该设备在指定的时间内没有更新内存中的心跳数据,则检测是否有在redis中更新心跳
String strHeartTime = stringRedisTemplate.opsForValue().get(entry.getKey() +
PropertyConf.config.getProperty("redis.heart.suffix"));
if (strHeartTime == null || Long.valueOf(strHeartTime) < time){
// 设备同时在内存和redis中都没有数据心跳,可判断发生故障,向AS推送故障信息
DataEntity dataEntity = new DataEntity();
dataEntity.setDeviceEntity(new DeviceEntity());
dataEntity.getDeviceEntity().setDevUID(entry.getKey());
dataEntity.setType(Integer.valueOf(PropertyConf.config.getProperty("server.data.fault")));
DeviceEntity deviceEntity = new DeviceEntity();
// deviceEntity.setNsServerEntity(ServerRegiste.nsServerEntity);
deviceEntity.setDevUID(dataEntity.getDeviceEntity().getDevUID());
deviceEntity.setStatus(3);
try {
deviceService.deviceJoin(deviceEntity);
// TODO 向AS推送设备故障消息(暂定无需推送)
// RabbitMQUtil.sendMessage(JsonUtil.toJson(deviceEntity), PropertyConf.config.getProperty("fault.data.pub.queue"));
}catch (Exception e){
LOGGER.error("系统错误", e);
}
LOGGER.info("设备" + entry.getKey() + "出现故障!");
}else {
// 设备在内存中没有心跳,而在redis中存在心跳,表示设备已经连接到其他ns服务器,删除本地注册信息以及下发数据信息
DEVICE_JOIN_DATA.remove(entry.getKey());
WAIT_ACK_DOWN_DATA.remove(entry.getKey());
WAIT_DOWN_DATA.remove(entry.getKey());
DEVICE_FOR_PATTERN.remove(entry.getKey());
}
// 设备在内存中没有心跳,删除本地网络管道、心跳缓存
UPLOAD_DATA_SPLIT.remove(CHANNEL_ENTITY_MAP.get(entry.getKey()).getChannelHandlerContext());
CHANNEL_ENTITY_MAP.remove(entry.getKey());
heartDate.remove(entry.getKey());
}
}
}
}
下一篇: div垂直居中的方法