Tips搬砖日记如何实时获取设备的延迟
CAMELLIA如何实时获取设备的延迟
今天了解到一个功能,如何获取一个设备延迟,并加以监控。搜索了一下资源,大概了解可以通过两个方式获取。
- Ping请求+Springboot定时任务
- Http请求+Springboot定时任务
前提:实时获取设备延迟的前提是目标设备必须在线且可通过网络访问(支持ICMP或HTTP/HTTPS等协议),并且你拥有必要的访问权限。设备和本地网络应允许Ping或HTTP请求,并确保网络环境稳定、时间同步准确。
1. 测试Ping和HTTP获取设备延迟
1.1 使用Ping测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.net.InetAddress;
public class PingTest { public static void main(String[] args) { while (true) { try { String ipAddress = "camelliaxiaohua.online"; InetAddress inet = InetAddress.getByName(ipAddress); long startTime = System.currentTimeMillis(); boolean reachable = inet.isReachable(5000); long endTime = System.currentTimeMillis(); if (reachable) { System.out.println("Ping成功,延迟时间: " + (endTime - startTime) + " 毫秒"); } else { System.out.println("Ping失败,主机不可达"); } } catch (Exception e) { e.printStackTrace(); } } } }
|
正常的实时 ping 请求对服务器的资源消耗通常很小,如上图测试所示(两核cpu)。ping
命令使用的是 ICMP(Internet Control Message Protocol)协议,它的主要作用是测试两台设备之间的网络连通性。ICMP 请求非常轻量,且不涉及复杂的计算或数据处理,因此对服务器的资源占用(CPU、内存、带宽等)很少。
下面就是不正常的操作,请勿模仿。
1. 频繁的大量 ping 请求:如果你以非常高的频率(如每秒数百次)持续向服务器发送 ping 请求,可能会占用网络带宽,尤其是在高并发的情况下,可能导致网络流量增加,影响其他服务。
2. 大规模分布式 ping(DDoS 攻击):如果有大量的设备同时向服务器发送 ping 请求(例如,DDoS 攻击中的 ping flood),可能会使服务器的网络资源被耗尽,导致服务变慢甚至宕机。
1.2 使用HTTP测试
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
| import java.net.HttpURLConnection; import java.net.URL;
public class HttpPingByHttpURLConnection { public static void main(String[] args) { while (true) { try { String urlString = "https://camelliaxiaohua.online"; URL url = new URL(urlString); long startTime = System.currentTimeMillis(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); connection.connect(); int responseCode = connection.getResponseCode(); long endTime = System.currentTimeMillis();
if (responseCode == 200) { System.out.println("请求成功,延迟时间: " + (endTime - startTime) + " 毫秒"); } else { System.out.println("请求失败,响应码: " + responseCode); } connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } } }
|
2. 使用定时任务实现实时监控
思路:后端使用SpringBoot定时任务获取设备延时。然后使用WebSocket定时将网络延迟数据实时推送给所有已连接的WebSocket客户端。在前端通过JavaScript与服务器建立WebSocket连接(如ws://localhost:8080/latency-ws
),接收延迟数据。
2.1 实现WebSocket的配置
1. 创建一个WebSocket配置类,用于注册WebSocket处理器。
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
| package networklatency.config;
import networklatency.controller.LatencyWebSocketHandler; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer {
private final LatencyWebSocketHandler latencyWebSocketHandler;
public WebSocketConfig(LatencyWebSocketHandler latencyWebSocketHandler) { this.latencyWebSocketHandler = latencyWebSocketHandler; }
@Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(latencyWebSocketHandler, "/latency-ws").setAllowedOrigins("*"); } }
|
2.2 实现WebSocket处理器
2. 创建一个LatencyWebSocketHandler
来管理WebSocket连接,并在定时任务中推送延迟结果。
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
| package networklatency.controller;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.List;
@Component public class LatencyWebSocketHandler extends TextWebSocketHandler {
private List<WebSocketSession> sessions = new ArrayList<>();
@Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); }
public void afterConnectionClosed(WebSocketSession session, boolean status) throws Exception { sessions.remove(session); }
public void broadcastLatency(String message) { for (WebSocketSession session : sessions) { try { session.sendMessage(new TextMessage(message)); } catch (Exception e) { e.printStackTrace(); } } } }
|
2.3 获取设备延迟
3. 实现SpringBoot定时任务,获取设备延迟并进行WebSocket消息推送。
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 networklatency.service.impl;
import networklatency.controller.LatencyWebSocketHandler; import networklatency.service.NetworkMonitorService; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL;
@Service public class NetworkMonitorServiceImpl implements NetworkMonitorService {
private final LatencyWebSocketHandler webSocketHandler;
public NetworkMonitorServiceImpl(LatencyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; }
@Override @Scheduled(fixedRate = 1000) public Long pingDevice() { String host = "camelliaxiaohua.online"; try { InetAddress address = InetAddress.getByName(host);
long startTime = System.currentTimeMillis(); boolean reachable = address.isReachable(2000); long endTime = System.currentTimeMillis();
long latency = endTime - startTime; if (reachable) { System.out.println("Ping成功,延迟时间: " + latency + " 毫秒"); } else { System.out.println("无法到达 " + host); } webSocketHandler.broadcastLatency("Ping Latency: " + latency + " ms"); return latency; } catch (Exception e) { e.printStackTrace(); } return 50000000L; }
@Override @Scheduled(fixedRate = 1000) public Long checkHttpLatency() { String urlString = "https://camelliaxiaohua.online"; try { URL url = new URL(urlString); long startTime = System.currentTimeMillis();
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(2000); connection.setReadTimeout(2000); connection.connect(); int responseCode = connection.getResponseCode(); long endTime = System.currentTimeMillis(); long latency = endTime - startTime;
if (responseCode == 200) { System.out.println("请求成功,延迟时间: " + latency + " 毫秒"); } else { System.out.println("请求失败,响应码: " + responseCode); } connection.disconnect();
webSocketHandler.broadcastLatency("HTTP Latency: " + latency + " ms"); return latency; } catch (Exception e) { e.printStackTrace(); } return 50000000L; } }
|
2.4 其他配置