修复延迟基线bug

Timer改成线程池,修复系统时间改变导致定时任务无法执行的bug
This commit is contained in:
2026-09-29 20:10:57 +08:00
parent 100fad7d18
commit 862b860020
13 changed files with 260 additions and 202 deletions
@@ -17,14 +17,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
@@ -67,7 +61,7 @@ public class KLALBController {
public HighAccuracyClock getClock() {
return clock;
}
private final long TIME_WINDOW=2000000000L;
private final long TIME_WINDOW=50000000000L;
private SpeedAndTrafficMonitorDataImpl linkMonitor = new SpeedAndTrafficMonitorDataImpl(
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "up", 100,TIME_WINDOW ),
new HashMapTimestampMonitor<UUID>(HighAccuracyClock.SYSTEM_CLOCK, "down", 100, TIME_WINDOW));
@@ -104,23 +98,9 @@ public class KLALBController {
public List<InetAddress> getDnsAddresses() {
return dnsAddresses;
}
private ScheduledExecutorService scheduleTimer=Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(),new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return ThreadTool.makeVDaemonThreadIfSupport("计时器线程", r);
}
});
public ScheduledExecutorService getScheduleTimer() {
return scheduleTimer;
}
private Timer twk = new Timer("网卡检测扫描计时器", true);
private TimerTask tsk1 = new TimerTask() {
private Runnable tsk1 = new Runnable() {
@Override
public void run() {
@@ -306,7 +286,7 @@ public class KLALBController {
return srv6Router.getLocator().getAddress().toInet6Address().equals(inetAddress);
}
private TimerTask tsk2 = new TimerTask() {
private Runnable tsk2 = new Runnable() {
@Override
public void run() {
@@ -734,8 +714,8 @@ public class KLALBController {
private void loadController() {
this.apiServer = new KLALBRoutingProtocolAPIServer(routingProtocol, this);
this.apiClient = new KLALBRoutingProtocolAPIClient(routingProtocol);
twk.schedule(tsk1, 5000, 5000);
twk.schedule(tsk2, 5000, 5000);
KLALBScheduler.getScheduler().scheduleAtFixedRate(tsk1, 5000, 5000,TimeUnit.MILLISECONDS);
KLALBScheduler.getScheduler().scheduleAtFixedRate(tsk2, 5000, 5000,TimeUnit.MILLISECONDS);
}
public KLALBController() {
@@ -753,17 +733,10 @@ public class KLALBController {
}
protected void initKLALB(boolean enableVirtualAdapter, IPv6AddressGroup selfg) {
ThreadTool.makeVDaemonThread("线路性能采样线程", ()->{
while(true) {
KLALBScheduler.getScheduler().scheduleAtFixedRate( ()->{
linkMonitor.update();
datatMonitor.update();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
},1,1,TimeUnit.MILLISECONDS);
loadSRv6ProtocolStack(selfg, enableVirtualAdapter);
loadController();
}
@@ -856,9 +829,8 @@ public class KLALBController {
return srv6Router;
}
private Timer trtr = new Timer("路由表刷新计时器", true);
{
trtr.scheduleAtFixedRate(new TimerTask() {
KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
@@ -869,9 +841,9 @@ public class KLALBController {
srv6Router.updateRouteTabel();
}
}
}, 100, 100);
}, 100, 100, TimeUnit.MILLISECONDS);
trtr.scheduleAtFixedRate(new TimerTask() {
KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
@@ -880,7 +852,7 @@ public class KLALBController {
}
}
}, 10, 10);
}, 1, 1,TimeUnit.MILLISECONDS);
}
public IPv6Packet createPacketToAddress(IPv6Address addr, int flowlabel, IPv6Packet.IPv6Payload packet) {
@@ -13,6 +13,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@@ -570,20 +572,17 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
private ThreadParker tpk=new ThreadParker();
private StateManager stateManager;
private MonitorUpdater monitorUpdater;
private ScheduledFuture<?> monitorUpdater;
private class MonitorUpdater implements Runnable{
@Override
public void run() {
while (!closed) {
if(closed) {
monitorUpdater.cancel(false);
}else{
status.updateReliability();
if(status.getState()!=LinkStatus.DOWN) {
monitor.update();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@@ -755,8 +754,7 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
protected void startIO() {
stateManager=new StateManager();
monitorUpdater=new MonitorUpdater();
ThreadTool.makeVDaemonThread("线路性能采样线程", monitorUpdater).start();
monitorUpdater=KLALBScheduler.getScheduler().scheduleAtFixedRate(new MonitorUpdater(),1,1, TimeUnit.MILLISECONDS);
ThreadTool.makeVDaemonThread("远程线路状态线程", stateManager).start();
}
@@ -0,0 +1,19 @@
package org.kne.cloud.network.klalb;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public class KLALBScheduler {
private static final ScheduledExecutorService scheduler;
static {
scheduler= Executors.newScheduledThreadPool( Runtime.getRuntime().availableProcessors(),
(r) -> {
Thread t = new Thread(r, "KLALB-Scheduler");
t.setDaemon(true); // 守护线程,不阻止 JVM 退出
return t;
});
}
public static ScheduledExecutorService getScheduler(){
return scheduler;
}
}
@@ -7,8 +7,8 @@ import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import javax.imageio.ImageIO;
import javax.swing.*;
@@ -37,8 +37,7 @@ import org.kne.ui.YScrollPane;
public class KLALBStateGUI3 extends XFrame {
// ==================== 定时任务相关 ====================
private TimerTask tsk, tsk2, tsk3, tsk4, tsk5; // 各种定时任务
private Timer t, t2, t3; // 定时器
private ScheduledFuture<?> tsk, tsk2, tsk3, tsk4, tsk5; // 各种定时任务
// ==================== 系统托盘相关 ====================
private SystemTray st; // 系统托盘
@@ -705,10 +704,6 @@ public class KLALBStateGUI3 extends XFrame {
* 初始化定时器
*/
private void initTimers(KLALBController kc) {
t3 = new Timer("监视器刷新线程", true);
t2 = new Timer("仪表盘刷新线程", true);
t = new Timer("状态刷新线程", true);
// 创建刷新任务
createRefreshTask(kc, ysp);
}
@@ -1322,9 +1317,9 @@ public class KLALBStateGUI3 extends XFrame {
private void createRefreshTask(KLALBController kc, YScrollPane ysp) {
// 线路状态刷新任务
if (tsk != null) {
tsk.cancel();
tsk.cancel(false);
}
tsk = new TimerTask() {
tsk =KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
if (isVisible()) {
@@ -1382,28 +1377,26 @@ public class KLALBStateGUI3 extends XFrame {
ysp.updateScrool();
}
}
};
t.scheduleAtFixedRate(tsk, 1000, 1000);
}, 1000, 1000, TimeUnit.MILLISECONDS);
// 仪表盘数据刷新任务
if (tsk2 != null) {
tsk2.cancel();
tsk2.cancel(false);
}
tsk2 = new TimerTask() {
tsk2 =KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (isVisible()) {
updateDashboardData(kc);
}
}
};
t2.scheduleAtFixedRate(tsk2, 100, 100);
}, 100, 100,TimeUnit.MILLISECONDS);
// 网络图刷新任务
if (tsk5 != null) {
tsk5.cancel();
tsk5.cancel(false);
}
tsk5 = new TimerTask() {
tsk5 = KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (isVisible()) {
@@ -1415,8 +1408,7 @@ public class KLALBStateGUI3 extends XFrame {
graph.revalidate();
}
}
};
t.scheduleAtFixedRate(tsk5, 1000, 1000);
}, 1000, 1000,TimeUnit.MILLISECONDS);
}
/**
@@ -1764,7 +1756,7 @@ public class KLALBStateGUI3 extends XFrame {
public void close() {
setVisible(false);
if (tsk != null) {
tsk.cancel();
tsk.cancel(false);
}
if (st != null) {
st.remove(ti);
@@ -4,8 +4,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Scanner;
import java.util.UUID;
import javax.swing.JPanel;
@@ -26,6 +25,7 @@ import org.kne.cloud.network.ipv6.IPv6Address;
import org.kne.cloud.network.ipv6.IPv6AddressGroup;
import org.kne.cloud.network.ipv6.IPv6Packet;
import org.kne.cloud.network.klalb.KLALBRemoteLink;
import org.kne.cloud.network.klalb.KLALBScheduler;
import org.kne.cloud.network.monitor.LinkStatus;
import org.kne.cloud.network.monitor.TimestampMonitorValue;
import org.kne.math.Long128;
@@ -38,21 +38,18 @@ import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.swing.JSlider;
public class LineMonitorGUI extends XFrame {
private Timer timer;
private Timer timer1;
private Timer timer2;
private Timer timer3;
private Timer timer4;
private TimerTask tsk3;
private ScheduledFuture<?> tsk3;
private TimerTask tsk4, tsk5,tsk6,tsk7;
private TimerTask d1;
private TimerTask d2;
private TimerTask d3;
private TimerTask d4;
private ScheduledFuture<?> tsk4, tsk5,tsk6,tsk7;
private ScheduledFuture<?> d1;
private ScheduledFuture<?> d2;
private ScheduledFuture<?> d3;
private ScheduledFuture<?> d4;
private TimeSeries spdup = new TimeSeries(UIEnv.getRsb().getString("uploadspeed"));
private TimeSeries spddown = new TimeSeries(UIEnv.getRsb().getString("downloadspeed"));
@@ -386,49 +383,45 @@ public class LineMonitorGUI extends XFrame {
@Override
public void setVisible(boolean b) {
if (b) {
if (timer == null) {
timer = new Timer();
timer1 = new Timer();
timer2 = new Timer();
timer3 = new Timer();
timer4 = new Timer();
tsk3 = new TimerTask() {
if (tsk3 == null) {
tsk3 = KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
updateTraffic();
}
};
tsk4 = new TimerTask() {
}, 25, 25, TimeUnit.MILLISECONDS);
tsk4 = KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
recordSpeedData();
}
};
}, 10, 10, TimeUnit.MILLISECONDS);;
tsk5 = new TimerTask() {
tsk5 =KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
recordDelayData();
}
};
tsk6 = new TimerTask() {
}, 10, 10, TimeUnit.MILLISECONDS);
tsk6 =KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
recordBufferData();
}
};
tsk7 = new TimerTask() {
}, 10, 10, TimeUnit.MILLISECONDS);
tsk7 = KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
recordCongestionData();
}
};
d1 = new TimerTask() {
}, 25, 25, TimeUnit.MILLISECONDS);
d1 = KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
@@ -440,8 +433,8 @@ public class LineMonitorGUI extends XFrame {
}
}
}
};
d2 = new TimerTask() {
} ,25, 25, TimeUnit.MILLISECONDS);
d2 = KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
@@ -454,8 +447,8 @@ public class LineMonitorGUI extends XFrame {
}
}
};
d3 = new TimerTask() {
}, 25, 25, TimeUnit.MILLISECONDS);
d3 = KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
@@ -468,8 +461,8 @@ public class LineMonitorGUI extends XFrame {
}
}
};
d4 = new TimerTask() {
}, 25, 25, TimeUnit.MILLISECONDS);
d4 =KLALBScheduler.getScheduler().scheduleAtFixedRate( new Runnable() {
@Override
public void run() {
@@ -482,51 +475,32 @@ public class LineMonitorGUI extends XFrame {
}
}
};
timer.scheduleAtFixedRate(tsk3, 25, 25);
timer1.scheduleAtFixedRate(tsk4, 10, 10);
timer1.scheduleAtFixedRate(d1, 25, 25);
timer2.scheduleAtFixedRate(tsk5, 10, 10);
timer2.scheduleAtFixedRate(d2, 25, 25);
timer3.scheduleAtFixedRate(tsk6, 10, 10);
timer3.scheduleAtFixedRate(d3, 25, 25);
timer4.scheduleAtFixedRate(tsk7, 25, 25);
timer4.scheduleAtFixedRate(d4, 25, 25);
}, 25, 25, TimeUnit.MILLISECONDS);
}
} else {
if (tsk3 != null)
tsk3.cancel();
tsk3.cancel(false);
if (tsk4 != null)
tsk4.cancel();
tsk4.cancel(false);
if (tsk5 != null)
tsk5.cancel();
tsk5.cancel(false);
if (tsk6 != null)
tsk6.cancel();
tsk6.cancel(false);
if (tsk7 != null)
tsk7.cancel();
tsk7.cancel(false);
if (d1 != null)
d1.cancel();
d1.cancel(false);
if (d2 != null)
d2.cancel();
d2.cancel(false);
if (d3 != null)
d3.cancel();
d3.cancel(false);
if (d4 != null)
d4.cancel();
if (timer != null)
timer.cancel();
if (timer1 != null)
timer1.cancel();
if (timer2 != null)
timer2.cancel();
if (timer3 != null)
timer3.cancel();
if (timer4 != null)
timer4.cancel();
timer = null;
d4.cancel(false);
tsk3=null;
}
super.setVisible(b);
}
@@ -8,6 +8,8 @@ import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import org.kne.cloud.network.klalb.KLALBScheduler;
import org.kne.concurrent.*;
import org.kne.cloud.network.NetworkPacket;
import org.kne.cloud.network.congestion.CongestionAlgorithm;
@@ -254,7 +256,7 @@ public class KLTPOutputStream extends OutputStream implements KLTPPacketConsumer
}
}
};
tt=controller.getScheduleTimer().scheduleAtFixedRate (r, delaytime, delaytime,TimeUnit.NANOSECONDS);
tt= KLALBScheduler.getScheduler().scheduleWithFixedDelay(r, delaytime, delaytime,TimeUnit.NANOSECONDS);
}
IOException ioex=ioe.get();
@@ -67,6 +67,11 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
return recordPacket(key,clock.getCurrentTimeNanos(),count,length);
}
public boolean recordPacket(K key, int count, int length, long delay, long delayMin) {
return recordPacket(key, clock.getCurrentTimeNanos(),count, length, delay,delayMin);
}
public boolean recordPacket(K key,int count, int length, long delay) {
return recordPacket(key, clock.getCurrentTimeNanos(),count, length, delay);
}
@@ -75,17 +80,22 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
return recordPacket(key, timestamp,count, length, Long.MAX_VALUE / 1024);
}
@Override
public boolean recordPacket(K key, Long128 timestamp, int count, int length, long dsndDelay) {
return recordPacket(key, timestamp, count, length, dsndDelay,dsndDelay);
}
/**
* 记录数据包 - 使用插入排序保持列表有序,添加时间戳验证
*/
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) {
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay, long dsndDelayMin) {
// 验证时间戳的合理性
validateTimestamp(timestamp);
// 快速路径:尝试sequence=0
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp,count, length, delay);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp,count, length, delay,dsndDelayMin);
autoCleanup(cleanupThreshold);
rwLock.writeLock().lock();
@@ -461,6 +471,48 @@ public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K> {
}
}
/**
* 从已排序的列表中计算数据量 - 优化版本,只需要startTime
*/
private long calculateMinDelayFromSortedList(List<TimestampMonitorValue> sortedList, Long128 startTime) {
if (sortedList.isEmpty()) {
return 0;
}
// 使用二分查找找到第一个 >= startTime 的元素位置
int startIndex = findFirstValidIndexFromSorted(sortedList, startTime);
if (startIndex >= sortedList.size()) {
return 0;
}
// 计算从startIndex到末尾的所有数据量(因为数据包不会来自未来)
long sum = Long.MAX_VALUE/1024;
for (int i = startIndex; i < sortedList.size(); i++) {
sum =Math.min(sortedList.get(i).getDelayMin(),sum) ;
}
return sum;
}
@Override
public long calculateMinDelay(long timeWindowNs){
return calculateMinDelay(clock.getCurrentTimeNanos(),timeWindowNs);
}
@Override
public long calculateMinDelay(Long128 currentTime, long timeWindowNs){
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
rwLock.readLock().lock();
try {
return calculateMinDelayFromSortedList(entries, startTime);
} finally {
rwLock.readLock().unlock();
}
}
private volatile TimestampMonitorValue recent=null;
@Override
public TimestampMonitorValue getRecentDelayEntry() {
@@ -76,15 +76,22 @@ private String name;
return recordPacket(key,clock.getCurrentTimeNanos(),count,length,delay);
}
@Override
public boolean recordPacket(K key, int count, int length, long delay, long delayMin) {
return recordPacket(key,clock.getCurrentTimeNanos(),count,length,delay,delayMin);
}
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) {
return recordPacket(key,timestamp,count,length,delay,delay);
}
/**
* 超高性能记录数据包 - 针对路由器优化
*/
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay) {
public boolean recordPacket(K key, Long128 timestamp,int count, int length, long delay,long delayMin) {
autoCleanup(cleanupThreshold);
// 快速路径:尝试sequence=0
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey,timestamp, count,length,delay);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey,timestamp, count,length,delay,delayMin);
if (entries.putIfAbsent(monitorKey, monitorValue) == null) {
totalDataSize.add(length);
@@ -304,7 +311,18 @@ private String name;
// TODO 自动生成的方法存根
return 0;
}
@Override
@Override
public long calculateMinDelay(long timeWindowNs) {
return 0;
}
@Override
public long calculateMinDelay(Long128 currentTime, long timeWindowNs) {
return 0;
}
@Override
public TimestampMonitorValue getRecentDelayEntry() {
// TODO 自动生成的方法存根
return null;
@@ -19,26 +19,28 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
upSampler.update();
downSampler.update();
if(upSampler.getSnapshotPacketCount()>0&&upSampler.getSnapshotTotalDelay()>0) {
getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos());
long odelay=upSampler.getMinDelayNanos();
getUploadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, upSampler.getAvgDelayNanos(),upSampler.getMinDelayNanos());
/*long odelay=upSampler.getMinDelayNanos();
if(outDelayMin==Long.MAX_VALUE||odelay<=outDelayMin) {
outDelayMin=odelay;
}else{
outDelayMin=Math.min(odelay, outDelayMin+10000);
}
}*/
}
if(downSampler.getSnapshotPacketCount()>0&&downSampler.getSnapshotTotalDelay()>0) {
getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos());
getDownloadBandwidth(). recordPacket(KLALBUtils.createGlobalUUID(),0, 0, downSampler.getAvgDelayNanos(),downSampler.getMinDelayNanos());
long idelay=downSampler.getMinDelayNanos();
if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) {
/*if(inDelayMin==Long.MAX_VALUE||idelay<=inDelayMin) {
inDelayMin=idelay;
}else{
inDelayMin=Math.min(idelay, inDelayMin+10000);
}
}*/
}
long time=System.nanoTime();
if(time-stime>timewindowmax) {
outDelayMin=getUploadBandwidth().calculateMinDelay(super.getTimeWindowMax());
inDelayMin=getDownloadBandwidth().calculateMinDelay(super.getTimeWindowMax());
stime=time;
}
}
@@ -11,13 +11,13 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
private TimestampMonitor<UUID>uploadBandwidth;
private TimestampMonitor<UUID>downloadBandwidth;
private long timewindow=1000000000L;
private long timewindowmax=1000000000L;
private long timewindowmax=50000000000L;
private BandwidthSampler upSampler=new BandwidthSampler();
private BandwidthSampler downSampler=new BandwidthSampler();
private final long TIME_WINDOW=2000000000L;
private final long TIME_WINDOW=50000000000L;
public SpeedAndTrafficMonitorDataImpl(HighAccuracyClock clock) {
super();
this.clock=clock;
@@ -184,25 +184,32 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
long op=uploadBandwidth.calculatePacketRate(timewindowmax);
long ip=uploadBandwidth.calculatePacketRate(timewindowmax);
if(os>outSpeeedMax) {
outSpeeedMax=(outSpeeedMax+os)/2;
outSpeeedMax=os;
}else {
outSpeeedMax=(outSpeeedMax*999+os)/1000;
}
if(is>inSpeedMax) {
inSpeedMax=(inSpeedMax+is)/2;
inSpeedMax=is;
}else {
inSpeedMax=(inSpeedMax*999+is)/1000;
}
if(op>outPPSMax) {
outPPSMax=(outPPSMax+op)/2;
outPPSMax=op;
}else {
outPPSMax=(outPPSMax*999+op)/1000;
}
if(ip>inPPSMax) {
inPPSMax=(inPPSMax+ip)/2;
inPPSMax=ip;
}else {
inPPSMax=(inPPSMax*999+ip)/1000;
}
}
}
protected long getTimeWindow() {
return timewindow;
}
protected long getTimeWindowMax() {
return timewindowmax;
}
}
@@ -1,7 +1,6 @@
package org.kne.cloud.network.monitor;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.ipv6.PacketID;
import org.kne.math.Long128;
/**
@@ -37,6 +36,9 @@ public interface TimestampMonitor<K> {
*/
boolean recordPacket(K key,int count, int length);
boolean recordPacket(K key, int count,int length, long dsndDelay);
boolean recordPacket(K key, int count, int length, long avgDelayNanos, long minDelayNanos);
/**
* 记录数据包(使用指定时间戳)
* @param key 数据包标识
@@ -49,7 +51,9 @@ public interface TimestampMonitor<K> {
boolean recordPacket(K key, Long128 timestamp, int count,int length, long dsndDelay);
boolean recordPacket(K key, int count,int length, long dsndDelay);
boolean recordPacket(K key, Long128 timestamp, int count,int length, long dsndDelay,long dsndDelayMin);
// ==================== 清理维护方法 ====================
@@ -146,7 +150,11 @@ public interface TimestampMonitor<K> {
long getRecentDelay();
TimestampMonitorValue getRecentDelayEntry();
long calculateMinDelay(long timeWindowNs);
long calculateMinDelay(Long128 currentTime, long timeWindowNs);
TimestampMonitorValue getRecentDelayEntry();
// ==================== 全局统计方法 ====================
@@ -8,22 +8,26 @@ public class TimestampMonitorValue implements Comparable<TimestampMonitorValue>
private final int length;
private final TimestampMonitorKey<?> key;
private long delay;
private long delayMin;
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp,int count, int length) {
this(key,timestamp,count,length,Long.MAX_VALUE/1024);
this(key,timestamp,count,length,Long.MAX_VALUE/1024,Long.MAX_VALUE/1024);
}
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp,int count, int length,long delay) {
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp,int count, int length,long delay,long delayMin) {
this.key = key;
this.timestamp = timestamp;
this.count=count;
this.length = length;
this.delay=delay;
this.delayMin=delayMin;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + count;
result = prime * result + (int) (delay ^ (delay >>> 32));
result = prime * result + (int) (delayMin ^ (delayMin >>> 32));
result = prime * result + length;
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
return result;
@@ -38,8 +42,12 @@ public class TimestampMonitorValue implements Comparable<TimestampMonitorValue>
if (getClass() != obj.getClass())
return false;
TimestampMonitorValue other = (TimestampMonitorValue) obj;
if (count != other.count)
return false;
if (delay != other.delay)
return false;
if (delayMin != other.delayMin)
return false;
if (length != other.length)
return false;
if (timestamp == null) {
@@ -52,8 +60,8 @@ public class TimestampMonitorValue implements Comparable<TimestampMonitorValue>
@Override
public String toString() {
return "TimestampMonitorValue [timestamp=" + timestamp + ", length=" + length + ", key=" + key + ", delay="
+ delay + "]";
return "TimestampMonitorValue [timestamp=" + timestamp + ", count=" + count + ", length=" + length
+ ", delay=" + delay + ", delayMin=" + delayMin + "]";
}
public Long128 getTimestamp() { return timestamp; }
@@ -73,6 +81,12 @@ public class TimestampMonitorValue implements Comparable<TimestampMonitorValue>
this.delay = delay;
}
public long getDelayMin() {
return delayMin;
}
public void setDelayMin(long delayMin) {
this.delayMin = delayMin;
}
@Override
public int compareTo(TimestampMonitorValue other) {
return this.timestamp.compareTo(other.timestamp);
@@ -12,11 +12,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiConsumer;
@@ -45,11 +44,13 @@ import org.kne.cloud.network.ipv6.PadNHopByHopTLV;
import org.kne.cloud.network.ipv6.PostcardEntry;
import org.kne.cloud.network.ipv6.RouteItem;
import org.kne.cloud.network.klalb.KLALBRemoteLink;
import org.kne.cloud.network.klalb.KLALBScheduler;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.cloud.network.klalb.PerformanceStrategy;
import org.kne.cloud.network.klalb.ui.PerformanceStrategyItem;
import org.kne.concurrent.HighPerformanceExecutor2;
import org.kne.concurrent.TimeoutConcurrentHashMap;
import org.kne.io.KNEChannels;
import org.pcap4j.packet.IllegalRawDataException;
import com.google.gson.internal.Pair;
@@ -850,7 +851,6 @@ public class SRv6Router {
private volatile long backplanePPSMax=0;
private volatile long prevTime=System.nanoTime();
private Timer backplaneTimer=new Timer();
private void updateBackplaneCounter() {
long curr=System.nanoTime();
long totalTime=timeAdder.getAndReset();
@@ -904,13 +904,13 @@ public class SRv6Router {
linkTabel.add(inLoopBack); // 添加到链路表
this.srhInserter=new SRHInsertNetworkLink(this,networkGroup);
linkTabel.add(srhInserter);
backplaneTimer.scheduleAtFixedRate(new TimerTask() {
KLALBScheduler.getScheduler().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
updateBackplaneCounter();
}
}, 100, 100);
}, 100, 100, TimeUnit.MILLISECONDS);
}
/*