fuliqi
2025-02-14 c6976365d5bfb39a32db8b541b1fe3ceb30c7826
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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("同步平台离线信息完成");
    }
}