package com.ycl.task;
|
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.ycl.platform.domain.entity.Platform;
|
import com.ycl.platform.domain.entity.PlatformOnline;
|
import com.ycl.platform.mapper.PlatformMapper;
|
import com.ycl.platform.service.PlatformOnlineService;
|
import com.ycl.system.entity.SysDictData;
|
import com.ycl.system.service.impl.SysDictTypeServiceImpl;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.stereotype.Component;
|
|
import java.io.IOException;
|
import java.net.InetAddress;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.TimeUnit;
|
|
/**
|
* 平台在线率定时任务
|
*
|
* @author:xp
|
* @date:2024/8/3 13:26
|
*/
|
@Slf4j
|
@RequiredArgsConstructor
|
@Component("platformTask")
|
public class PlatformTask {
|
|
private final RedisTemplate redisTemplate;
|
private final PlatformMapper platformMapper;
|
private final PlatformOnlineService platformOnlineService;
|
|
/**
|
* 该定时任务需要使用redis存储离线时长,并定期同步到mysql中
|
*/
|
private static final String REDIS_KEY_PREFIX = "platform_online_";
|
|
private static final String DICT_TYPE = "platform_online";
|
|
private static final ExecutorService executorService = new ThreadPoolExecutor(16,
|
64,
|
5000,
|
TimeUnit.SECONDS,
|
new ArrayBlockingQueue<>(1000),
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
);
|
|
/**
|
* ping平台是否在线
|
*
|
* @throws IOException
|
*/
|
public void ping() {
|
List<Platform> platformList = new LambdaQueryChainWrapper<>(platformMapper)
|
.isNotNull(Platform::getPlatformIP)
|
.list();
|
for (Platform platform : platformList) {
|
executorService.submit(() -> {
|
try {
|
Boolean reachable = Boolean.FALSE;
|
for (int tryTimes = 1; tryTimes < 3; tryTimes++) {
|
// 三秒未ping通重试一次,如果不行才扣分
|
reachable = InetAddress.getByName(platform.getPlatformIP()).isReachable(3000);
|
if (reachable) {
|
break;
|
}
|
}
|
if (!reachable) {
|
// 如果ping不通,离线时长加5秒
|
redisTemplate.opsForValue().increment(REDIS_KEY_PREFIX + platform.getPlatformIP(), 5);
|
log.warn(platform.getPlatformName() + "平台未ping通");
|
}
|
} catch (Exception e) {
|
log.error("检查平台连通性时发生d错误", e);
|
}
|
});
|
}
|
}
|
|
/**
|
* 每小时将redis中的平台离线数据同步到mysql
|
*
|
*/
|
public void synToMySQL() {
|
List<Platform> platformList = new LambdaQueryChainWrapper<>(platformMapper)
|
.isNotNull(Platform::getPlatformIP)
|
.list();
|
// 将java.util.Date转换为java.sql.Date
|
java.sql.Date sqlDate = new java.sql.Date(new Date().getTime());
|
|
for (Platform platform : platformList) {
|
Object outLineTime = redisTemplate.opsForValue().get(REDIS_KEY_PREFIX + platform.getPlatformIP());
|
Integer outlineTimeSed = Objects.isNull(outLineTime) ? 0 : (Integer) outLineTime;
|
PlatformOnline one = new LambdaQueryChainWrapper<>(platformOnlineService.getBaseMapper())
|
.eq(PlatformOnline::getPlatformId, platform.getId())
|
.eq(PlatformOnline::getCreateDate, sqlDate)
|
.one();
|
if (Objects.isNull(one)) {
|
one = new PlatformOnline();
|
one.setPlatformId(platform.getId());
|
one.setCreateDate(sqlDate);
|
one.setTodayOutlineSed(outlineTimeSed);
|
} else {
|
one.setTodayOutlineSed(one.getTodayOutlineSed() + outlineTimeSed);
|
}
|
one.setPlatformId(platform.getId());
|
one.setCreateDate(sqlDate);
|
|
platformOnlineService.saveOrUpdate(one);
|
}
|
log.info("同步平台离线信息完成");
|
}
|
}
|