io.github.icodegarden.nutrient.lang.util.SystemUtils Maven / Gradle / Ivy
package io.github.icodegarden.nutrient.lang.util;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.channels.SocketChannel;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;
import com.sun.management.OperatingSystemMXBean;
import io.github.icodegarden.nutrient.lang.tuple.Tuple2;
import io.github.icodegarden.nutrient.lang.tuple.Tuples;
import lombok.extern.slf4j.Slf4j;
/**
*
* @author Fangfang.Xu
*
*/
public abstract class SystemUtils {
public static final DateTimeFormatter STANDARD_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static final DateTimeFormatter STANDARD_DATETIME_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss");
public static final DateTimeFormatter STANDARD_DATETIMEMS_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
public static final String OS_NAME = System.getProperty("os.name");
private static boolean isLinuxPlatform = false;
private static boolean isWindowsPlatform = false;
static {
if (OS_NAME != null && OS_NAME.toLowerCase().contains("linux")) {
isLinuxPlatform = true;
}
if (OS_NAME != null && OS_NAME.toLowerCase().contains("windows")) {
isWindowsPlatform = true;
}
}
public static boolean isWindowsPlatform() {
return isWindowsPlatform;
}
public static boolean isLinuxPlatform() {
return isLinuxPlatform;
}
public static String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
/**
* 该接口有一定的耗时
*
* @return 本机所处网络中的IP
*/
public static String getIp() {
Tuple2, List> tuple2 = getIpv46s();
List ipv4Result = tuple2.getT1();
List ipv6Result = tuple2.getT2();
// prefer ipv4
if (!ipv4Result.isEmpty()) {
for (String ip : ipv4Result) {
if (ip.startsWith("127.0") || ip.startsWith("192.168")) {
continue;
}
return ip;
}
return ipv4Result.get(ipv4Result.size() - 1);
} else if (!ipv6Result.isEmpty()) {
return ipv6Result.get(0);
}
// fallback
if (!ipv4Result.isEmpty()) {
return ipv4Result.get(0);
}
// no possible
return null;
}
/**
* 获取本机所有ipv4地址 该接口有一定的耗时
*/
public static List getIpv4s() {
Tuple2, List> tuple2 = getIpv46s();
return tuple2.getT1();
}
/**
* 获取本机所有ipv6地址 该接口有一定的耗时
*/
public static List getIpv6s() {
Tuple2, List> tuple2 = getIpv46s();
return tuple2.getT2();
}
/**
* 获取本机所有ip地址 该接口有一定的耗时
*/
public static List getIps() {
Tuple2, List> tuple2 = getIpv46s();
List t1 = tuple2.getT1();
t1.addAll(tuple2.getT2());
return t1;
}
/**
* 获取本机所有ip地址 该接口有一定的耗时
*
* @return ipv4,ipv6
* @throws on fail
*/
private static Tuple2, List> getIpv46s() throws IllegalStateException {
try {
// Traversal Network interface to get the first non-loopback and non-private
// address
Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
List ipv4Result = new LinkedList();
List ipv6Result = new LinkedList();
while (enumeration.hasMoreElements()) {
final NetworkInterface networkInterface = enumeration.nextElement();
final Enumeration en = networkInterface.getInetAddresses();
while (en.hasMoreElements()) {
final InetAddress address = en.nextElement();
if (!address.isLoopbackAddress()) {
if (address instanceof Inet6Address) {
ipv6Result.add(normalizeHostAddress(address));
} else {
ipv4Result.add(normalizeHostAddress(address));
}
}
}
}
if (ipv4Result.isEmpty()) {
final InetAddress localHost = InetAddress.getLocalHost();
String localhost = normalizeHostAddress(localHost);
ipv4Result.add(localhost);
}
return Tuples.of(ipv4Result, ipv6Result);
} catch (Exception e) {
throw new IllegalStateException("Failed to obtain local address", e);
}
}
/**
*
* @param ip
* @param port
* @return ip:port
*/
public static String formatIpPort(String ip, int port) {
return ip + ":" + port;
}
public static Tuple2 resolveIpPort(String ipport) {
String[] split = ipport.split(":");
String ip = split[0];
int port = Integer.parseInt(split[1]);
return Tuples.of(ip, port);
}
public static String normalizeHostAddress(final InetAddress localHost) {
if (localHost instanceof Inet6Address) {
return "[" + localHost.getHostAddress() + "]";
} else {
return localHost.getHostAddress();
}
}
public static SocketAddress string2SocketAddress(final String addr) {
int split = addr.lastIndexOf(":");
String host = addr.substring(0, split);
String port = addr.substring(split + 1);
InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port));
return isa;
}
public static String socketAddress2String(final SocketAddress addr) {
StringBuilder sb = new StringBuilder();
InetSocketAddress inetSocketAddress = (InetSocketAddress) addr;
sb.append(inetSocketAddress.getAddress().getHostAddress());
sb.append(":");
sb.append(inetSocketAddress.getPort());
return sb.toString();
}
public static SocketChannel connect(SocketAddress remote) {
return connect(remote, 1000 * 5);
}
public static SocketChannel connect(SocketAddress remote, final int timeoutMillis) {
SocketChannel sc = null;
try {
sc = SocketChannel.open();
sc.configureBlocking(true);
sc.socket().setSoLinger(false, -1);
sc.socket().setTcpNoDelay(true);
sc.socket().setReceiveBufferSize(1024 * 64);
sc.socket().setSendBufferSize(1024 * 64);
sc.socket().connect(remote, timeoutMillis);
sc.configureBlocking(false);
return sc;
} catch (Exception e) {
if (sc != null) {
try {
sc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return null;
}
// ------------------------------------------------------------
private static VMRuntime vmRuntime;
static {
try {
vmRuntime = new OperatingSystemMXBeanRuntime();
} catch (Throwable e) {
vmRuntime = new FallbackRuntime();
}
}
public static VMRuntime getVmRuntime() {
return vmRuntime;
}
public interface VMRuntime {
/**
* @return byte
*/
long getTotalPhysicalMemorySize();
/**
* @return byte
*/
long getFreePhysicalMemorySize();
/**
* @return byte
*/
long getUsedPhysicalMemorySize();
/**
* @return byte
*/
long getTotalSwapSpaceSize();
/**
* @return byte
*/
long getFreeSwapSpaceSize();
/**
* @return byte
*/
long getUsedSwapSpaceSize();
/**
* Xmx
*
* @return byte
*/
long getJvmMaxMemory();
/**
* 已分配的JVM内存
*
* @return byte
*/
long getJvmTotalMemory();
/**
* @return byte
*/
long getJvmFreeMemory();
/**
* @return byte
*/
long getJvmUsedMemory();
/**
* 系统使用率
*
* @return 0-1.0
*/
double getSystemCpuLoad();
/**
* java进程使用率
*
* @return 0-1.0
*/
double getProcessCpuLoad();
// WIN10
// JDK8
// Xss256
//
// 综合结论:每秒能使用多少个线程进行并发,取决于内存和cpu哪个更容易达到阈值
//
//
// CPU测试---------------------------------------------------------------------------------------
// 结论
// 每核频率为2.10GHz的工作站
// 每秒并发10000线程,每个线程的业务是创建3000个对象
// 结果在linux 逻辑8核环境下稳定占CPU不超过120%,即每核占不超过15%
// 以此计算1核时占cpu不超过80%时,可每秒并发线程=(10000/1.20)*0.8=6600,生产环境的服务器cpu保守也按此性能计算=6600*1=6600,保险起见性能需要*3倍=6600/3=2200
// 即1核最多可承担2200个线程并发
//
//
// 内存测试---------------------------------------------------------------------------------------
// 结论(带业务4G 2G):每1000个线程 + 1000个对象占堆内存80M,进程占内存120M
// 用于生产保险起见*3倍计算,堆内和进程内存哪个容易达到阈值计算。
// 例如用户配置2G堆内存线程数约2048/80/3=8500个,4G物理内存线程数约4096/120/3=11300个,最终取8500个
// 例如用户配置2G堆内存线程数约2048/80/3=8500个,2.5G物理内存线程数约2560/120/3=7100个,最终取7100个
default long maxConcurrentThreadsPerSecond() {
long totalPhysicalMemoryMB = getVmRuntime().getTotalPhysicalMemorySize() / 1024 / 1024;
long maxTotalPhysicalMemoryThreads = (totalPhysicalMemoryMB / 120 / 3) * 1000;
long xmxMemory = getVmRuntime().getJvmMaxMemory() / 1024 / 1024;
long maxXmxMemoryThreads = (xmxMemory / 80 / 3) * 1000;
int cpuCores = Runtime.getRuntime().availableProcessors();
int maxCpuThreads = cpuCores * 3300;
long max = Math.min(maxTotalPhysicalMemoryThreads, maxXmxMemoryThreads);
max = Math.min(max, maxCpuThreads);
return max;
}
}
private static class OperatingSystemMXBeanRuntime implements VMRuntime {
private final OperatingSystemMXBean systemMXBean = (OperatingSystemMXBean) ManagementFactory
.getOperatingSystemMXBean();
private final Runtime runtime = Runtime.getRuntime();
/**
* @return byte
*/
public long getTotalPhysicalMemorySize() {
return systemMXBean.getTotalPhysicalMemorySize();
}
/**
* @return byte
*/
public long getFreePhysicalMemorySize() {
return systemMXBean.getFreePhysicalMemorySize();
}
/**
* @return byte
*/
public long getUsedPhysicalMemorySize() {
return systemMXBean.getTotalPhysicalMemorySize() - systemMXBean.getFreePhysicalMemorySize();
}
/**
* @return byte
*/
public long getTotalSwapSpaceSize() {
return systemMXBean.getTotalSwapSpaceSize();
}
/**
* @return byte
*/
public long getFreeSwapSpaceSize() {
return systemMXBean.getFreeSwapSpaceSize();
}
/**
* @return byte
*/
public long getUsedSwapSpaceSize() {
return systemMXBean.getTotalSwapSpaceSize() - systemMXBean.getFreeSwapSpaceSize();
}
/**
* Xmx
*
* @return byte
*/
public long getJvmMaxMemory() {
return runtime.maxMemory();
}
/**
* 已分配的JVM内存
*
* @return byte
*/
public long getJvmTotalMemory() {
return runtime.totalMemory();
}
/**
* @return byte
*/
public long getJvmFreeMemory() {
return runtime.freeMemory();
}
/**
* @return byte
*/
public long getJvmUsedMemory() {
return getJvmMaxMemory() - getJvmFreeMemory();
}
/**
* 系统使用率,首次获取大约耗时1200ms
*
* @return 0-1.0
*/
public double getSystemCpuLoad() {
return systemMXBean.getSystemCpuLoad();
}
/**
* java进程使用率
*
* @return 0-1.0
*/
public double getProcessCpuLoad() {
return CACHE.processCpuLoad;
}
private final Cache CACHE = new Cache(3000);
private class Cache {
private double processCpuLoad;
private Cache(long periodMillis) {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(runnable -> {
Thread thread = new Thread(runnable, "Runtime Cache");
thread.setDaemon(true);
return thread;
});
scheduler.scheduleAtFixedRate(() -> {
try {
/**
* 每次耗时约20ms
*/
processCpuLoad = systemMXBean.getProcessCpuLoad();
} catch (Exception ignore) {
}
}, periodMillis, periodMillis, TimeUnit.MILLISECONDS);
}
}
}
private static class FallbackRuntime implements VMRuntime {
private final Runtime runtime = Runtime.getRuntime();
/**
* @return byte
*/
public long getTotalPhysicalMemorySize() {
return Long.MAX_VALUE;
}
/**
* @return byte
*/
public long getFreePhysicalMemorySize() {
return Long.MAX_VALUE;
}
/**
* @return byte
*/
public long getUsedPhysicalMemorySize() {
return 0;
}
/**
* @return byte
*/
public long getTotalSwapSpaceSize() {
return Long.MAX_VALUE;
}
/**
* @return byte
*/
public long getFreeSwapSpaceSize() {
return Long.MAX_VALUE;
}
/**
* @return byte
*/
public long getUsedSwapSpaceSize() {
return 0;
}
/**
* Xmx
*
* @return byte
*/
public long getJvmMaxMemory() {
return runtime.maxMemory();
}
/**
* 已分配的JVM内存
*
* @return byte
*/
public long getJvmTotalMemory() {
return runtime.totalMemory();
}
/**
* @return byte
*/
public long getJvmFreeMemory() {
return runtime.freeMemory();
}
/**
* @return byte
*/
public long getJvmUsedMemory() {
return getJvmMaxMemory() - getJvmFreeMemory();
}
/**
* 系统使用率,首次获取大约耗时1200ms
*
* @return 0-1.0
*/
public double getSystemCpuLoad() {
return 0;
}
/**
* java进程使用率
*
* @return 0-1.0
*/
public double getProcessCpuLoad() {
return 0;
}
}
// public static void main(String[] args) throws Exception {
// for(;;) {
// long start = System.currentTimeMillis();
// System.out.println(getTotalPhysicalMemorySize()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getFreePhysicalMemorySize()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getUsedPhysicalMemorySize()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println("---------------------------------");
//
//
// System.out.println(getTotalSwapSpaceSize()/1024/1024/1024);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getFreeSwapSpaceSize()/1024/1024/1024);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getUsedSwapSpaceSize()/1024/1024/1024);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println("---------------------------------");
// System.out.println(getJvmMaxMemory()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getJvmTotalMemory()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getJvmFreeMemory()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getJvmUsedMemory()/1024.0/1024.0/1024.0);
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println("---------------------------------");
// System.out.println(getSystemCpuLoad());
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println(getProcessCpuLoad());
// System.out.println("used:"+(System.currentTimeMillis() - start));
// System.out.println("---------------------------------");
//
// Thread.sleep(3000);
// System.out.println(".............................");
// }
//
// new Thread() {
// public void run() {
// for(;;) {
// System.out.println(getJvmMaxMemory()/1024.0/1024.0/1024.0);
// System.out.println(getJvmTotalMemory()/1024.0/1024.0/1024.0);
// System.out.println(getJvmFreeMemory()/1024.0/1024.0/1024.0);
// System.out.println(getJvmUsedMemory()/1024.0/1024.0/1024.0);
// System.out.println("---------------------------------");
// System.out.println(getSystemCpuLoad());
// System.out.println(getProcessCpuLoad());
// System.out.println("---------------------------------");
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// }
// }
// };
// }.start();
//
// ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy