WangHan
2024-09-12 d5855a4926926698b740bc6c7ba489de47adb68b
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
package tech.powerjob.worker.common.utils;
 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.common.serialize.JsonUtils;
import tech.powerjob.common.utils.HttpUtils;
import tech.powerjob.common.utils.NetUtils;
import tech.powerjob.common.utils.net.PingPongServer;
import tech.powerjob.common.utils.net.PingPongSocketServer;
 
import java.util.List;
 
/**
 * PowerJob Worker 专用的网络工具类
 *
 * @author tjq
 * @since 2024/2/8
 */
@Slf4j
public class WorkerNetUtils {
 
    private static final String SERVER_CONNECTIVITY_CHECK_URL_PATTERN = "http://%s/server/checkConnectivity?targetIp=%s&targetPort=%d";
 
    /**
     * 多网卡情况下,解析可与 server 通讯的本地 IP 地址
     * @param port 目标端口
     * @param serverAddress server 服务地址
     * @return 本机IP
     */
    public static String parseLocalBindIp(int port, List<String> serverAddress) {
        PingPongServer pingPongServer = null;
 
        try {
            pingPongServer = new PingPongSocketServer();
            pingPongServer.initialize(port);
            log.info("[WorkerNetUtils] initialize PingPongSocketServer successfully~");
 
            return NetUtils.getLocalHostWithNetworkInterfaceChecker(((networkInterface, inetAddress) -> {
 
                if (inetAddress == null) {
                    log.info("[WorkerNetUtils] [networkInterface:{}] skip due to inetAddress is null!", networkInterface);
                    return false;
                }
 
                String workerIp = inetAddress.getHostAddress();
                for (String address : serverAddress) {
                    String url = String.format(SERVER_CONNECTIVITY_CHECK_URL_PATTERN, address, workerIp, port);
                    try {
                        String resp = HttpUtils.get(url);
                        log.info("[WorkerNetUtils] [networkInterface:{},inetAddress:{}] check connectivity by url[{}], response: {}", networkInterface, inetAddress, url, resp);
                        if (StringUtils.isNotEmpty(resp)) {
                            ResultDTO<?> resultDTO = JsonUtils.parseObject(resp, ResultDTO.class);
                            boolean ret = Boolean.TRUE.toString().equalsIgnoreCase(String.valueOf(resultDTO.getData()));
                            if (ret) {
                                return true;
                            }
                        }
                    } catch (Exception ignore) {
                    }
                }
                return false;
            }));
 
        } catch (Exception e) {
            log.warn("[WorkerNetUtils] PingPongSocketServer failed to start, which may result in an incorrectly bound IP, please pay attention to the initialize log.", e);
        } finally {
            if (pingPongServer != null) {
                try {
                    pingPongServer.close();
                    log.info("[WorkerNetUtils] close PingPongSocketServer successfully~");
                } catch (Exception e) {
                    log.warn("[WorkerNetUtils] close PingPongSocketServer failed!", e);
                }
            }
        }
 
        return NetUtils.getLocalHostWithNetworkInterfaceChecker(null);
    }
 
}