引入pom
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.5.0</version>
</dependency>
1.创建OS工具类
import lombok.extern.slf4j.Slf4j;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import java.math.RoundingMode;
import java.text.DecimalFormat;
@Slf4j
public class OSUtils {
private static final SystemInfo SI = new SystemInfo();
private static HardwareAbstractionLayer hal = SI.getHardware();
public static final String TWO_DECIMAL = "0.00";
/**
* whether is windows
* @return true if windows
*/
public static boolean isWindows() {
return getOSName().startsWith("Windows");
}
/**
* get current OS name
* @return current OS name
*/
public static String getOSName() {
return System.getProperty("os.name");
}
/**
* get memory usage
* Keep 2 decimal
* @return percent %
*/
public static String memoryUsage() {
GlobalMemory memory = hal.getMemory();
double memoryUsage = (memory.getTotal() - memory.getAvailable() ) * 0.1 / memory.getTotal() * 10*100;
DecimalFormat df = new DecimalFormat(TWO_DECIMAL);
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(memoryUsage);
}
/**
* load average
*
* @return load average
*/
public static String loadAverage() {
double loadAverage = hal.getProcessor().getSystemLoadAverage(2)[1];
DecimalFormat df = new DecimalFormat(TWO_DECIMAL);
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(loadAverage);
}
/**
* get cpu usage
*
* @return cpu usage
*/
public static String cpuUsage() {
CentralProcessor processor = hal.getProcessor();
double cpuUsage = processor.getSystemCpuLoad()*100;
DecimalFormat df = new DecimalFormat(TWO_DECIMAL);
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(cpuUsage);
}
}
IP工具类
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;
public class IpUtils {
/**
* 获取请求真实ip地址,避免获取代理ip
*/
public static String getIpAddress(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= Objects.requireNonNull(inet).getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
/**
* get local host
* @return host
*/
public static String getHost(){
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "127.0.0.1";
}
public static void main(String[] args) {
System.out.println(getHost());
}
}
2.创建监控对象
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ServerInfoVO {
private String serverCode;
private String serverIp;
private String cpuUse;
private String menUse;
private String load;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
}
3.创建server启动监听
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.ws.websocket.util.IpUtils;
import com.ws.websocket.util.OSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class Server implements ApplicationRunner {
@Resource
private StringRedisTemplate stringRedisTemplate;
public static final String CPU_HEART = "CPU_HEART";
@Value("${xxl.job.executor.title}")
private String title;
@Value("${xxl.job.executor.port}")
private String port;
private void startup(){
try {
heartbeat();
log.info("start Quartz server...");
} catch (Exception e) {
log.error("start Quartz failed : " + e.getMessage(), e);
}
}
private void heartbeat() {
ScheduledExecutorService heartbeatMasterService = newDaemonThreadScheduledExecutor("executor-heart-Thread",1);
Runnable heartBeatThread = heartBeatThread();
heartbeatMasterService.
scheduleAtFixedRate(heartBeatThread, 1, 1, TimeUnit.MINUTES);
}
/**
* heartbeat thread implement
* @return
*/
private Runnable heartBeatThread(){
log.info("start heart beat thread...");
return () -> {
ServerInfoVO serverInfoVO = ServerInfoVO.builder()
.serverIp(IpUtils.getHost()+"-"+port)
.serverCode(title)
.cpuUse(OSUtils.cpuUsage()+"%")
.menUse(OSUtils.memoryUsage()+"%")
.load(OSUtils.loadAverage())
.updateTime(new Date())
.build();
stringRedisTemplate.convertAndSend(CPU_HEART,JSONObject.toJSONString(serverInfoVO));
};
}
@Override
public void run(ApplicationArguments args) throws Exception {
startup();
}
public static ScheduledExecutorService newDaemonThreadScheduledExecutor(String threadName, int corePoolSize) {
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat(threadName)
.build();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
executor.setRemoveOnCancelPolicy(true);
return executor;
}
}
4.配置redis
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
* @Author: wangsheng
* @Data: 2022/8/16 16:40
*/
@Slf4j
@Configuration
public class RedisListenerConfig {
/**
* 订阅操作频道
*
* @param connectionFactory connectionFactory
* @return RedisMessageListenerContainer
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageReceive listenerAdapter){
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter,new PatternTopic("CPU_HEART"));
log.info(listenerAdapter.getClass().getName() + " 订阅频道 {}", "CPU_HEART");
return container;
}
}
5.订阅消息
package com.ws.websocket.config;
import com.alibaba.fastjson.JSON;
import com.ws.websocket.util.ServerHelper;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
@Component
public class MessageReceive implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
try {
ServerInfoVO serverInfoVO = JSON.parseObject(message.toString(),ServerInfoVO.class);
ServerHelper.put(serverInfoVO.getServerIp(),serverInfoVO);
}catch (Exception e){
e.printStackTrace();
}
}
}
import com.ws.websocket.config.ServerInfoVO;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class ServerHelper {
private static final Map<String, ServerInfoVO> maps = new ConcurrentHashMap<>();
public static void put(String key, ServerInfoVO serverInfoVO) {
maps.put(key, serverInfoVO);
}
public static List<ServerInfoVO> get() {
List<ServerInfoVO> list = new ArrayList<>();
Collection<ServerInfoVO> collection = maps.values();
for (ServerInfoVO serverInfoVO : collection) {
serverInfoVO.setServerIp(null);
long differ = new Date().getTime() - Objects.requireNonNull(serverInfoVO.getUpdateTime()).getTime();
if (differ > 100000) {
maps.remove(serverInfoVO.getServerCode());
continue;
}
list.add(serverInfoVO);
}
return list;
}
}
6.获取服务器资源信息
public Object getResourceMonitor() {
return ServerHelper.get();
}
5284

被折叠的 条评论
为什么被折叠?



