Skip to content

Commit

Permalink
Merge branch '4.3.7_v2'
Browse files Browse the repository at this point in the history
  • Loading branch information
KFCFans committed Feb 9, 2024
2 parents 9b7c237 + ea919b1 commit 78b58d0
Show file tree
Hide file tree
Showing 63 changed files with 755 additions and 230 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# English | [简体中文](./README_zhCN.md)

<p align="center">
🏮PowerJob 全体成员祝大家龙年腾飞,新的一年身体健康,万事如意,阖家欢乐,幸福安康!🏮
</p>

<p align="center">
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/logo.png" alt="PowerJob" title="PowerJob" width="557"/>
</p>
Expand Down
4 changes: 4 additions & 0 deletions README_zhCN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# [English](./README.md) | 简体中文

<p align="center">
🏮PowerJob 全体成员祝大家龙年腾飞,新的一年身体健康,万事如意,阖家欢乐,幸福安康!🏮
</p>

<p align="center">
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/logo.png" alt="PowerJob" title="PowerJob" width="557"/>
</p>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>tech.powerjob</groupId>
<artifactId>powerjob</artifactId>
<version>4.3.6</version>
<version>4.3.7</version>
<packaging>pom</packaging>
<name>powerjob</name>
<url>http://www.powerjob.tech</url>
Expand Down
6 changes: 3 additions & 3 deletions powerjob-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
<parent>
<artifactId>powerjob</artifactId>
<groupId>tech.powerjob</groupId>
<version>4.3.6</version>
<version>4.3.7</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>powerjob-client</artifactId>
<version>4.3.6</version>
<version>4.3.7</version>
<packaging>jar</packaging>

<properties>
<junit.version>5.9.1</junit.version>
<fastjson.version>1.2.83</fastjson.version>
<powerjob.common.version>4.3.6</powerjob.common.version>
<powerjob.common.version>4.3.7</powerjob.common.version>

<mvn.shade.plugin.version>3.2.4</mvn.shade.plugin.version>
</properties>
Expand Down
4 changes: 2 additions & 2 deletions powerjob-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<parent>
<artifactId>powerjob</artifactId>
<groupId>tech.powerjob</groupId>
<version>4.3.6</version>
<version>4.3.7</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>powerjob-common</artifactId>
<version>4.3.6</version>
<version>4.3.7</version>
<packaging>jar</packaging>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package tech.powerjob.common.enhance;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ScheduledExecutorService;

/**
* 安全的 runnable,可防止因抛出异常导致周期性任务终止
* 使用 {@link ScheduledExecutorService} 执行任务时,推荐继承此类捕获并打印异常,避免因为抛出异常导致周期性任务终止
*
* @author songyinyin
* @since 2023/9/20 15:52
*/
@Slf4j
public abstract class SafeRunnable implements Runnable{
@Override
public void run() {
try {
run0();
} catch (Exception e) {
log.error("[SafeRunnable] run failed", e);
}
}

protected abstract void run0();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package tech.powerjob.common.enhance;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ScheduledExecutorService;

/**
* 使用 {@link ScheduledExecutorService} 执行任务时,推荐使用此对象包装一层,避免因为抛出异常导致周期性任务终止
*
* @author songyinyin
* @since 2023/9/20 16:04
*/
@Slf4j
public class SafeRunnableWrapper implements Runnable {

private final Runnable runnable;

public SafeRunnableWrapper(Runnable runnable) {
this.runnable = runnable;
}

@Override
public void run() {
try {
runnable.run();
} catch (Exception e) {
log.error("[SafeRunnableWrapper] run failed", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public static boolean checkIpPortAvailable(String ip, int port) {
* @return 本机 IP 地址
*/
public static String getLocalHost() {
return getLocalHostWithNetworkInterfaceChecker(null);
}

public static String getLocalHostWithNetworkInterfaceChecker(NetworkInterfaceChecker networkInterfaceChecker) {
if (HOST_ADDRESS != null) {
return HOST_ADDRESS;
}
Expand All @@ -87,31 +91,39 @@ public static String getLocalHost() {
return HOST_ADDRESS = addressFromJVM;
}

InetAddress address = getLocalAddress();
InetAddress address = getLocalAddress(networkInterfaceChecker);
if (address != null) {
return HOST_ADDRESS = address.getHostAddress();
}
return LOCALHOST_VALUE;
}

/**
* 隔离调用 scope,核心场景才能直接调用 getLocalHost,方便查看使用点
* @return IP
*/
public static String getLocalHost4Test() {
return getLocalHost();
}

/**
* Find first valid IP from local network card
*
* @return first valid local IP
*/
public static InetAddress getLocalAddress() {
public static InetAddress getLocalAddress(NetworkInterfaceChecker networkInterfaceChecker) {
if (LOCAL_ADDRESS != null) {
return LOCAL_ADDRESS;
}
InetAddress localAddress = getLocalAddress0();
InetAddress localAddress = getLocalAddress0(networkInterfaceChecker);
LOCAL_ADDRESS = localAddress;
return localAddress;
}

private static InetAddress getLocalAddress0() {
private static InetAddress getLocalAddress0(NetworkInterfaceChecker networkInterfaceChecker) {
// @since 2.7.6, choose the {@link NetworkInterface} first
try {
InetAddress addressOp = getFirstReachableInetAddress( findNetworkInterface());
InetAddress addressOp = getFirstReachableInetAddress( findNetworkInterface(networkInterfaceChecker));
if (addressOp != null) {
return addressOp;
}
Expand Down Expand Up @@ -161,7 +173,7 @@ private static InetAddress getFirstReachableInetAddress(NetworkInterface network
* @return If no {@link NetworkInterface} is available , return <code>null</code>
* @since 2.7.6
*/
public static NetworkInterface findNetworkInterface() {
public static NetworkInterface findNetworkInterface(NetworkInterfaceChecker networkInterfaceChecker) {

List<NetworkInterface> validNetworkInterfaces = emptyList();
try {
Expand All @@ -176,7 +188,11 @@ public static NetworkInterface findNetworkInterface() {
// Try to find the preferred one
for (NetworkInterface networkInterface : validNetworkInterfaces) {
if (isPreferredNetworkInterface(networkInterface)) {
log.info("[Net] use preferred network interface: {}", networkInterface.getDisplayName());
log.info("[Net] use preferred network interface: {}", networkInterface);
return networkInterface;
}
if (isPassedCheckNetworkInterface(networkInterface, networkInterfaceChecker)) {
log.info("[Net] use PassedCheckNetworkInterface: {}", networkInterface);
return networkInterface;
}
}
Expand All @@ -191,6 +207,25 @@ public static NetworkInterface findNetworkInterface() {
return first(validNetworkInterfaces);
}

/**
* 通过用户方法判断是否为目标网卡
* @param networkInterface networkInterface
* @param networkInterfaceChecker 判断方法
* @return true or false
*/
static boolean isPassedCheckNetworkInterface(NetworkInterface networkInterface, NetworkInterfaceChecker networkInterfaceChecker) {
if (networkInterfaceChecker == null) {
return false;
}
log.info("[Net] try to choose NetworkInterface by NetworkInterfaceChecker, current NetworkInterface: {}", networkInterface);
try {
return networkInterfaceChecker.ok(networkInterface, getFirstReachableInetAddress(networkInterface));
} catch (Exception e) {
log.warn("[Net] isPassedCheckerNetworkInterface failed, current networkInterface: {}", networkInterface, e);
}
return false;
}

private static Optional<InetAddress> toValidAddress(InetAddress address) {
if (address instanceof Inet6Address) {
Inet6Address v6Address = (Inet6Address) address;
Expand Down Expand Up @@ -344,4 +379,9 @@ static boolean ignoreInterfaceByConfig(String interfaceName) {
}
return false;
}

@FunctionalInterface
public interface NetworkInterfaceChecker {
boolean ok(NetworkInterface networkInterface, InetAddress inetAddress);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tech.powerjob.common.utils.net;

import java.io.Closeable;

/**
* socket 服务器,用于进行连通性测试
*
* @author tjq
* @since 2024/2/8
*/
public interface PingPongServer extends Closeable {

void initialize(int port) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package tech.powerjob.common.utils.net;

import lombok.extern.slf4j.Slf4j;
import tech.powerjob.common.utils.CommonUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
* 简易服务器
*
* @author tjq
* @since 2024/2/8
*/
@Slf4j
public class PingPongSocketServer implements PingPongServer {

private Thread thread;

private ServerSocket serverSocket;

private volatile boolean terminated = false;

@Override
public void initialize(int port) throws Exception{
serverSocket = new ServerSocket(port);

thread = new Thread(() -> {
while (true) {
if (terminated) {
return;
}
// 接收连接,如果没有连接,accept() 方法会阻塞
try (Socket socket = serverSocket.accept();OutputStream outputStream = socket.getOutputStream();) {
outputStream.write(PingPongUtils.PONG.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
} catch (Exception e) {
if (!terminated) {
log.warn("[PingPongSocketServer] process accepted socket failed!", e);
}
}
}
}, "PingPongSocketServer-Thread");

thread.start();
}

@Override
public void close() throws IOException {
terminated = true;
CommonUtils.executeIgnoreException(() -> serverSocket.close());
thread.interrupt();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package tech.powerjob.common.utils.net;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

/**
* socket 连通性助手
*
* @author tjq
* @since 2024/2/8
*/
@Slf4j
public class PingPongUtils {

static final String PING = "ping";
static final String PONG = "pong";

/**
* 验证目标 IP 和 端口的连通性
* @param targetIp 目标 IP
* @param targetPort 目标端口
* @return true or false
*/
public static boolean checkConnectivity(String targetIp, int targetPort) {

try (Socket s = new Socket(targetIp, targetPort);InputStream is = s.getInputStream();OutputStream os = s.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is))) {

// 发送 PING 请求
os.write(PING.getBytes(StandardCharsets.UTF_8));
os.flush();

//读取服务器返回的消息
String content = br.readLine();

if (PONG.equalsIgnoreCase(content)) {
return true;
}
} catch (UnknownHostException e) {
log.warn("[SocketConnectivityUtils] unknown host: {}:{}", targetIp, targetPort);
} catch (IOException e) {
log.warn("[SocketConnectivityUtils] IOException: {}:{}, msg: {}", targetIp, targetPort, ExceptionUtils.getMessage(e));
} catch (Exception e) {
log.error("[SocketConnectivityUtils] unknown exception for check ip: {}:{}", targetIp, targetPort, e);
}

return false;
}
}
6 changes: 3 additions & 3 deletions powerjob-common/src/test/java/NetUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ public class NetUtilsTest {

@Test
public void testOrigin() {
System.out.println(NetUtils.getLocalHost());
System.out.println(NetUtils.getLocalHost4Test());
}

@Test
public void testPreferredNetworkInterface() {
System.setProperty(PowerJobDKey.PREFERRED_NETWORK_INTERFACE, "en5");
System.out.println(NetUtils.getLocalHost());
System.out.println(NetUtils.getLocalHost4Test());
}

@Test
public void testIgnoredNetworkInterface() {
System.setProperty(PowerJobDKey.IGNORED_NETWORK_INTERFACE_REGEX, "utun.|llw.");
System.out.println(NetUtils.getLocalHost());
System.out.println(NetUtils.getLocalHost4Test());
}

}

0 comments on commit 78b58d0

Please sign in to comment.