KLALB V3.4

This commit is contained in:
Administrator
2025-11-15 11:08:16 +08:00
parent 306bfd36f7
commit 8842566ee2
160 changed files with 18540 additions and 4512 deletions
@@ -0,0 +1,460 @@
package org.kne.cloud.network.monitor;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.math.Long128;
public class ArrayListTimestampMonitor<K> implements TimestampMonitor<K>{
private HighAccuracyClock clock;
private String name;
// 使用LongAdder替代AtomicLong,在高并发下性能更好
private final LongAdder totalDataSize = new LongAdder();
private final LongAdder totalPackets = new LongAdder();
// 配置参数
private final int maxRetry;
private final long cleanupThreshold;
// 使用ArrayList存储数据
private final List<TimestampMonitorValue> entries = new ArrayList<>();
// 读写锁用于保护ArrayList的并发访问
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
// 时间戳验证容差(纳秒),考虑到网络延迟和时钟同步
private static final long TIMESTAMP_TOLERANCE_NS = 10_000_000L; // 10毫秒
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HighAccuracyClock getClock() {
return clock;
}
protected ArrayListTimestampMonitor(HighAccuracyClock clock, String name, int maxRetry, long cleanupThreshold) {
super();
this.clock = clock;
this.name = name;
this.maxRetry = maxRetry;
this.cleanupThreshold = cleanupThreshold;
}
public ArrayListTimestampMonitor() {
this(new HighAccuracyClock(), "TimestampMonitor", 100, 1000000000L);
}
public ArrayListTimestampMonitor(HighAccuracyClock clock, String name) {
this(clock, name, 100, 1000000000L);
}
private volatile long prev = System.nanoTime();
public boolean recordPacket(K key, int length) {
return recordPacket(key, clock.getCurrentTimeNanos(), length);
}
/**
* 记录数据包 - 使用插入排序保持列表有序,添加时间戳验证
*/
public boolean recordPacket(K key, Long128 timestamp, int length) {
// 验证时间戳的合理性
validateTimestamp(timestamp);
// 快速路径:尝试sequence=0
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey, timestamp, length);
autoCleanup(cleanupThreshold);
rwLock.writeLock().lock();
try {
// 使用二分查找插入排序,保持列表有序
insertSorted(monitorValue);
totalDataSize.add(length);
totalPackets.increment();
return true;
} finally {
rwLock.writeLock().unlock();
}
}
/**
* 验证时间戳的合理性
*/
private void validateTimestamp(Long128 timestamp) {
/* BigInteger currentTime = clock.getCurrentTimeNanos();
BigInteger maxAllowedTime = currentTime.add(BigInteger.valueOf(TIMESTAMP_TOLERANCE_NS));
if (timestamp.compareTo(maxAllowedTime) > 0) {
throw new IllegalArgumentException(
String.format("Timestamp %s is in the future (current time: %s, tolerance: %d ns)",
timestamp, currentTime, TIMESTAMP_TOLERANCE_NS));
}
*/
}
/**
* 使用二分查找进行插入排序,保持列表有序
*/
private void insertSorted(TimestampMonitorValue newValue) {
if (entries.isEmpty()) {
entries.add(newValue);
return;
}
// 优化:检查是否可以快速添加到末尾(大部分数据包是按时间顺序到达的)
TimestampMonitorValue lastValue = entries.get(entries.size() - 1);
if (newValue.getTimestamp().compareTo(lastValue.getTimestamp()) >= 0) {
entries.add(newValue);
return;
}
// 使用二分查找找到插入位置
int insertIndex = findInsertIndex(newValue.getTimestamp());
entries.add(insertIndex, newValue);
}
/**
* 使用二分查找找到插入位置
*/
private int findInsertIndex(Long128 timestamp) {
int low = 0;
int high = entries.size() - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
Long128 midTimestamp = entries.get(mid).getTimestamp();
int cmp = timestamp.compareTo(midTimestamp);
if (cmp < 0) {
high = mid - 1;
} else if (cmp > 0) {
low = mid + 1;
} else {
// 时间戳相等,插入到相同时间戳的后面
return findLastEqualIndex(mid, timestamp) + 1;
}
}
return low;
}
/**
* 找到相同时间戳的最后一个元素的索引
*/
private int findLastEqualIndex(int startIndex, Long128 timestamp) {
int index = startIndex;
while (index < entries.size() - 1 &&
entries.get(index + 1).getTimestamp().equals(timestamp)) {
index++;
}
return index;
}
private void autoCleanup(long th) {
long curr = System.nanoTime();
if (curr - prev > th) {
prev = curr;
cleanup();
}
}
public void cleanup() {
cleanup(clock.getCurrentTimeNanos(), cleanupThreshold);
}
/**
* 清理旧记录 - 由于列表已排序,直接使用二分查找
*/
public void cleanup(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
rwLock.writeLock().lock();
try {
// 使用二分查找找到第一个不过期的元素位置
int firstValidIndex = findFirstValidIndex(startTime);
if (firstValidIndex > 0) {
// 删除所有过期的元素
entries.subList(0, firstValidIndex).clear();
}
} finally {
rwLock.writeLock().unlock();
}
prev=System.nanoTime();
}
/**
* 使用二分查找找到第一个时间戳 >= startTime 的元素索引
*/
private int findFirstValidIndex(Long128 startTime) {
int low = 0;
int high = entries.size();
while (low < high) {
int mid = (low + high) >>> 1;
Long128 midTimestamp = entries.get(mid).getTimestamp();
if (midTimestamp.compareTo(startTime) < 0) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
public long calculateDataVolume(long timeWindowNs) {
return calculateDataVolume(clock.getCurrentTimeNanos(), timeWindowNs);
}
/**
* 高性能数据量计算 - 优化:由于数据包不会来自未来,只需要查找startTime
*/
public long calculateDataVolume(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
rwLock.readLock().lock();
try {
return calculateDataVolumeFromSortedList(entries, startTime);
} finally {
rwLock.readLock().unlock();
}
}
/**
* 从已排序的列表中计算数据量 - 优化版本,只需要startTime
*/
private long calculateDataVolumeFromSortedList(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 = 0;
for (int i = startIndex; i < sortedList.size(); i++) {
sum += sortedList.get(i).getLength();
}
return sum;
}
/**
* 在已排序列表中找到第一个时间戳 >= startTime 的索引
*/
private int findFirstValidIndexFromSorted(List<TimestampMonitorValue> sortedList, Long128 startTime) {
int low = 0;
int high = sortedList.size();
while (low < high) {
int mid = (low + high) >>> 1;
Long128 midTimestamp = sortedList.get(mid).getTimestamp();
if (midTimestamp.compareTo(startTime) < 0) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
public long calculatePacketCount(long timeWindowNs) {
return calculatePacketCount(clock.getCurrentTimeNanos(), timeWindowNs);
}
/**
* 高性能包数计算 - 优化:由于数据包不会来自未来,只需要查找startTime
*/
public long calculatePacketCount(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
rwLock.readLock().lock();
try {
return calculatePacketCountFromSortedList(entries, startTime);
} finally {
rwLock.readLock().unlock();
}
}
/**
* 从已排序的列表中计算包数 - 优化版本,只需要startTime
*/
private long calculatePacketCountFromSortedList(List<TimestampMonitorValue> sortedList,
Long128 startTime) {
if (sortedList.isEmpty()) {
return 0;
}
int startIndex = findFirstValidIndexFromSorted(sortedList, startTime);
if (startIndex >= sortedList.size()) {
return 0;
}
// 计算从startIndex到末尾的所有包数(因为数据包不会来自未来)
return sortedList.size() - startIndex;
}
public long calculateBandwidth(long timeWindowNs) {
return calculateBandwidth(clock.getCurrentTimeNanos(), timeWindowNs);
}
/**
* 计算带宽
*/
public long calculateBandwidth(Long128 currentTime, long timeWindowNs) {
if (timeWindowNs <= 0) {
return 0;
}
long dataVolume = calculateDataVolume(currentTime, timeWindowNs);
return (long) (dataVolume * 1000000000.0 / timeWindowNs);
}
public TrafficStats calculateTrafficStats(long timeWindowNs) {
return calculateTrafficStats(clock.getCurrentTimeNanos(), timeWindowNs);
}
/**
* 计算流量统计信息 - 优化:由于数据包不会来自未来,只需要查找startTime
*/
public TrafficStats calculateTrafficStats(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
rwLock.readLock().lock();
try {
return calculateTrafficStatsFromSortedList(entries, startTime, currentTime, timeWindowNs);
} finally {
rwLock.readLock().unlock();
}
}
/**
* 从已排序的列表中计算流量统计 - 优化版本
*/
private TrafficStats calculateTrafficStatsFromSortedList(List<TimestampMonitorValue> sortedList,
Long128 startTime, Long128 currentTime,
long timeWindowNs) {
TrafficStats stats = new TrafficStats();
stats.timeWindowNs = timeWindowNs;
stats.currentTime = currentTime;
if (sortedList.isEmpty()) {
return stats;
}
int startIndex = findFirstValidIndexFromSorted(sortedList, startTime);
if (startIndex >= sortedList.size()) {
return stats;
}
// 计算从startIndex到末尾的所有数据(因为数据包不会来自未来)
for (int i = startIndex; i < sortedList.size(); i++) {
TimestampMonitorValue value = sortedList.get(i);
stats.packetCount++;
stats.totalBytes += value.getLength();
if (stats.earliestTimestamp.equals(BigInteger.ZERO) ||
value.getTimestamp().compareTo(stats.earliestTimestamp) < 0) {
stats.earliestTimestamp = value.getTimestamp();
}
if (value.getTimestamp().compareTo(stats.latestTimestamp) > 0) {
stats.latestTimestamp = value.getTimestamp();
}
}
return stats;
}
// Getters
public long getTotalDataSize() { return totalDataSize.sum(); }
public long getTotalPackets() { return totalPackets.sum(); }
public int getEntryCount() {
rwLock.readLock().lock();
try {
return entries.size();
} finally {
rwLock.readLock().unlock();
}
}
public void reset() {
rwLock.writeLock().lock();
try {
totalDataSize.reset();
totalPackets.reset();
entries.clear();
} finally {
rwLock.writeLock().unlock();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append('\n');
sb.append(KLALBUtils.convertIBUint(totalDataSize.sum())).append("\t")
.append(KLALBUtils.convertIBUint(calculateBandwidth(Math.min(cleanupThreshold,1000000000L)))).append("/s\t");
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
AtomicLong along=new AtomicLong(0);
ArrayListTimestampMonitor<Long> monitor = new ArrayListTimestampMonitor<>(new HighAccuracyClock(),"Monitor",100,200000000L);
Thread t=new Thread(()->{
while(true) {
monitor.recordPacket(along.getAndIncrement(), 1000);
}
});
t.start();
Timer tx=new Timer();
tx.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 计算带宽
long testEndTime = System.nanoTime();
monitor.cleanup();
// 计算统计信息
// TrafficStats stats = monitor.calculateTrafficStats(1000000000L);
System.out.println(monitor);
System.out.println(KLALBUtils.convertUintNanoDefalut( System.nanoTime()-testEndTime));
}
}, 100, 100);
}
}
@@ -0,0 +1,275 @@
package org.kne.cloud.network.monitor;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Collectors;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.cloud.network.klalb.KLALBUtils;
import org.kne.math.Long128;
public class HashMapTimestampMonitor<K> implements TimestampMonitor<K> {
private HighAccuracyClock clock;
private String name;
// 使用LongAdder替代AtomicLong,在高并发下性能更好
private final LongAdder totalDataSize = new LongAdder();
private final LongAdder totalPackets = new LongAdder();
// 配置参数
private final int maxRetry;
private final long cleanupThreshold;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HighAccuracyClock getClock() {
return clock;
}
protected HashMapTimestampMonitor(HighAccuracyClock clock,String name, int maxRetry, long cleanupThreshold) {
super();
this.clock=clock;
this.name = name;
this.maxRetry = maxRetry;
this.cleanupThreshold = cleanupThreshold;
}
public HashMapTimestampMonitor() {
this(new HighAccuracyClock(),"TimestampMonitor",100, 1000000000L); // 默认最大重试100次,清理阈值1秒
}
public HashMapTimestampMonitor(HighAccuracyClock clock,String name) {
this(clock,name,100, 1000000000L); // 默认最大重试100次,清理阈值1秒
}
private final ConcurrentHashMap<TimestampMonitorKey<K>, TimestampMonitorValue> entries =
new ConcurrentHashMap<>();
private volatile long prev=System.nanoTime();
public boolean recordPacket(K key, int length) {
return recordPacket(key,clock.getCurrentTimeNanos(),length);
}
/**
* 超高性能记录数据包 - 针对路由器优化
*/
public boolean recordPacket(K key, Long128 timestamp, int length) {
autoCleanup(cleanupThreshold);
// 快速路径:尝试sequence=0
TimestampMonitorKey<K> monitorKey = new TimestampMonitorKey<>(key, 0);
TimestampMonitorValue monitorValue = new TimestampMonitorValue(monitorKey,timestamp, length);
if (entries.putIfAbsent(monitorKey, monitorValue) == null) {
totalDataSize.add(length);
totalPackets.increment();
return true;
}
// 重试路径(极少执行)
for (int sequence = 0; sequence < maxRetry; sequence++) {
monitorKey = new TimestampMonitorKey<>(key, sequence);
monitorValue = new TimestampMonitorValue(monitorKey,timestamp, length);
if (entries.putIfAbsent(monitorKey, monitorValue) == null) {
totalDataSize.add(length);
totalPackets.increment();
return true;
}
}
return false;
}
private void autoCleanup(long th) {
long curr=System.nanoTime();
if(curr-prev>th) {
prev=curr;
cleanup();
}
}
public void cleanup() {
cleanup(clock.getCurrentTimeNanos(),cleanupThreshold);
}
/**
*清理旧记录
*/
public void cleanup(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime .subtract(Long128.valueOf( timeWindowNs));
//System.out.println("clr");
entries.entrySet().removeIf(entry ->
entry.getValue().getTimestamp() .compareTo( startTime)<0);
prev=System.nanoTime();
}
/*public void cleanup(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime.subtract(Long128.valueOf(timeWindowNs));
// 并行筛选需要删除的键
List<Object> keysToRemove = entries.entrySet()
.parallelStream()
.filter(entry -> entry.getValue().getTimestamp().compareTo(startTime) < 0)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// 批量删除(如果entries是ConcurrentHashMap,可以并行删除)
keysToRemove.parallelStream().forEach(entries::remove);
System.out.println("remove:"+keysToRemove.size());
prev=System.nanoTime();
}*/
public long calculateDataVolume(long timeWindowNs) {
return calculateDataVolume(clock.getCurrentTimeNanos(),timeWindowNs);
}
/**
* 高性能数据量计算 - 使用并行流
*/
public long calculateDataVolume(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime .subtract(Long128.valueOf( timeWindowNs));
return entries.values().stream()
.filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&&
(value.getTimestamp().compareTo( currentTime) <=0) )
.mapToLong(TimestampMonitorValue::getLength)
.sum();
}
public long calculatePacketCount(long timeWindowNs) {
return calculatePacketCount(clock.getCurrentTimeNanos(),timeWindowNs);
}
/**
* 高性能包数计算 - 使用并行流
* 计算从n纳秒前到现在的时间窗口内传输的数据包数量
*/
public long calculatePacketCount(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime .subtract(Long128.valueOf( timeWindowNs));
return entries.values().parallelStream()
.filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&&
(value.getTimestamp().compareTo( currentTime) <=0) )
.count();
}
public long calculateBandwidth(long timeWindowNs) {
return calculateBandwidth(clock.getCurrentTimeNanos(),timeWindowNs);
}
/**
* 计算带宽 - 添加单位转换
*/
public long calculateBandwidth(Long128 currentTime, long timeWindowNs) {
if (timeWindowNs <= 0) {
return 0;
}
long dataVolume = calculateDataVolume(currentTime, timeWindowNs);
// System.out.println(dataVolume);
return (long) (dataVolume*1000000000.0/timeWindowNs);
}
public TrafficStats calculateTrafficStats(long timeWindowNs) {
return calculateTrafficStats(clock.getCurrentTimeNanos(),timeWindowNs);
}
/**
* 计算包数并同时获取带宽信息
*/
public TrafficStats calculateTrafficStats(Long128 currentTime, long timeWindowNs) {
Long128 startTime = currentTime .subtract(Long128.valueOf( timeWindowNs));
TrafficStats stats = entries.values().parallelStream()
.filter(value -> (value.getTimestamp() .compareTo( startTime )>=0)&&
(value.getTimestamp().compareTo( currentTime) <=0) )
.collect(
TrafficStats::new,
(ts, value) -> {
ts.packetCount++;
ts.totalBytes += value.getLength();
if (ts.earliestTimestamp .equals(Long128.ZERO) || (value.getTimestamp() .compareTo( ts.earliestTimestamp)<0)) {
ts.earliestTimestamp = value.getTimestamp();
}
if (value.getTimestamp() .compareTo( ts.latestTimestamp)>0) {
ts.latestTimestamp = value.getTimestamp();
}
},
(ts1, ts2) -> {
ts1.packetCount += ts2.packetCount;
ts1.totalBytes += ts2.totalBytes;
ts1.earliestTimestamp = ts1.earliestTimestamp.min( ts2.earliestTimestamp);
ts1.latestTimestamp = ts1.latestTimestamp.max( ts2.latestTimestamp);
}
);
stats.timeWindowNs = timeWindowNs;
stats.currentTime = currentTime;
return stats;
}
// Getters
public long getTotalDataSize() { return totalDataSize.sum(); }
public long getTotalPackets() { return totalPackets.sum(); }
public int getEntryCount() { return entries.size(); }
public void reset() {
totalDataSize.reset();
totalPackets.reset();
entries.clear();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append('\n');
sb.append(KLALBUtils.convertIBUint(totalDataSize.sum())).append("\t")
.append(KLALBUtils.convertIBUint(calculateBandwidth(Math.min(cleanupThreshold,1000000000L)))).append("/s\t");
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
HighAccuracyClock clk=new HighAccuracyClock();
HashMapTimestampMonitor<Long> monitor = new HashMapTimestampMonitor<>(clk,"Monitor",100,200000000L);
Thread t=new Thread(()->{
long l=0;
while(true) {
monitor.recordPacket(l++, 1000);
}
});
t.start();
Timer tx=new Timer();
tx.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 计算带宽
long testEndTime = System.nanoTime();
monitor.cleanup();
// 计算统计信息
// TrafficStats stats = monitor.calculateTrafficStats(1000000000L);
System.out.println(monitor);
System.out.println(KLALBUtils.convertUintNanoDefalut( System.nanoTime()-testEndTime)+monitor.entries.size());
}
}, 100, 100);
}
}
@@ -1,7 +1,5 @@
package org.kne.cloud.network.monitor;
import static org.kne.cloud.network.klalb.KLALBUtils.bytesUnit;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Consumer;
@@ -1,5 +0,0 @@
package org.kne.cloud.network.monitor;
public class NanoTimeSeries {
}
@@ -1,24 +1,26 @@
package org.kne.cloud.network.monitor;
import org.kne.cloud.network.klalb.KLALBUtils;
public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonitorDataImpl implements SpeedAndTrafficMonitorData,DelayMonitorData{
private volatile long outDelay;
private volatile long outDelay=Long.MAX_VALUE/1024;
private volatile long outDelayMin=Long.MAX_VALUE;
private volatile long outDelayAvg=Long.MAX_VALUE;
private long outDelayOld;
private volatile long outJitter;
private volatile long inDelay;
private volatile long inDelay=Long.MAX_VALUE/1024;
private volatile long inDelayMin=Long.MAX_VALUE;
private volatile long inDelayAvg=Long.MAX_VALUE;
private long inDelayOld;
private volatile long inJitter;
private volatile long latency;
private volatile long latency=Long.MAX_VALUE/1024;
private volatile long latencyMin=Long.MAX_VALUE;
private volatile long latencyAvg=Long.MAX_VALUE;
private long latencyOld;
@@ -170,7 +172,7 @@ public class SpeedAndTrafficAndDelayMonitorDataImpl extends SpeedAndTrafficMonit
@Override
public String toString() {
StringBuilder sb=new StringBuilder(super.toString());
sb.append(String.format("%.1f", outDelay/1000000.0) ).append("ms").append("\t").append(String.format("%.1f", inDelay/1000000.0) ).append("ms").append("\t").append(String.format("%.1f", outJitter/1000000.0) ).append("ms\t").append(String.format("%.1f", inJitter/1000000.0) ).append("ms\t");
sb.append(KLALBUtils.convertUintNanoDefalut( outDelay) ).append("s").append("\t").append(KLALBUtils.convertUintNanoDefalut( inDelay) ).append("s").append("\t").append(KLALBUtils.convertUintNanoDefalut( outJitter) ).append("s\t").append(KLALBUtils.convertUintNanoDefalut( inJitter) ).append("s\t");
return sb.toString();
}
@@ -1,15 +1,16 @@
package org.kne.cloud.network.monitor;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
public interface SpeedAndTrafficMonitorData extends MonitorData{
public long getInTraffic();
public long getOutTraffic();
public AtomicLong getInTrafficAL();
public LongAdder getInTrafficAL();
public AtomicLong getOutTrafficAL();
public LongAdder getOutTrafficAL();
public long getInSpeed();
@@ -21,9 +22,9 @@ public long getInPPS();
public long getOutPPS();
public AtomicLong getInPacketCounterAL();
public LongAdder getInPacketCounterAL();
public AtomicLong getOutPacketCounterAL();
public LongAdder getOutPacketCounterAL();
public long getInPacketCounter();
@@ -1,9 +1,10 @@
package org.kne.cloud.network.monitor;
import static org.kne.cloud.network.klalb.KLALBUtils.bytesUnit;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import org.kne.cloud.network.klalb.KLALBUtils;
public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements SpeedAndTrafficMonitorData {
@@ -11,8 +12,8 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
private long updatetime1=System.nanoTime();
private long updatetime2=System.nanoTime();
private volatile AtomicLong inTraffic=new AtomicLong();
private volatile AtomicLong outTraffic=new AtomicLong();
private volatile LongAdder inTraffic=new LongAdder();
private volatile LongAdder outTraffic=new LongAdder();
private long inTrafficOld=0;
@@ -43,7 +44,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
}
protected void createTask() {
getTimer().scheduleAtFixedRate(tmt, 0, 50);
getTimer().scheduleAtFixedRate(tmt, 0, 20);
}
protected void createTask1() {
@@ -61,18 +62,18 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
}
public long getInTraffic() {
return inTraffic.get();
return inTraffic.sum();
}
public long getOutTraffic() {
return outTraffic.get();
return outTraffic.sum();
}
public AtomicLong getInTrafficAL() {
public LongAdder getInTrafficAL() {
return inTraffic;
}
public AtomicLong getOutTrafficAL() {
public LongAdder getOutTrafficAL() {
return outTraffic;
}
@@ -121,25 +122,29 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
long d=System.nanoTime()-updatetime;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld;
inTrafficOld =inTraffic.get();
long inTrafficSum=inTraffic.sum();
long i=inTrafficSum-inTrafficOld;
inTrafficOld =inTrafficSum;
inSpeed= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld;
outTrafficOld =outTraffic.get();
long outTrafficSum=outTraffic.sum();
long o=outTrafficSum-outTrafficOld;
outTrafficOld =outTrafficSum;
outSpeed= (long) (o*1000000000.0/d);
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld;
inCounterOld =inCounter.get();
long inCounterSum=inCounter.sum();
long i=inCounterSum-inCounterOld;
inCounterOld =inCounterSum;
inPPS= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long i=outCounter.get()-outCounterOld;
outCounterOld =outCounter.get();
long outCounterSum=outCounter.sum();
long i=outCounterSum-outCounterOld;
outCounterOld =outCounterSum;
outPPS= (long) (i*1000000000.0/d);
}
}
@@ -180,26 +185,30 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
long d=System.nanoTime()-updatetime1;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld1;
inTrafficOld1 =inTraffic.get();
long inTrafficSum=inTraffic.sum();
long i=inTrafficSum-inTrafficOld1;
inTrafficOld1 =inTrafficSum;
inSpeedAvg= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld1;
outTrafficOld1 =outTraffic.get();
long outTrafficSum=outTraffic.sum();
long o=outTrafficSum-outTrafficOld1;
outTrafficOld1 =outTrafficSum;
outSpeedAvg= (long) (o*1000000000.0/d);
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld1;
inCounterOld1 =inCounter.get();
long inCounterSum=inCounter.sum();
long i=inCounterSum-inCounterOld1;
inCounterOld1 =inCounterSum;
inPPSAvg= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld1;
outCounterOld1 =outCounter.get();
long outCounterSum=outCounter.sum();
long o=outCounterSum-outCounterOld1;
outCounterOld1 =outCounterSum;
outPPSAvg= (long) (o*1000000000.0/d);
}
}
@@ -216,28 +225,32 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
long d=System.nanoTime()-updatetime2;
if(d!=0) {
if(inTraffic!=null) {
long i=inTraffic.get()-inTrafficOld2;
inTrafficOld2 =inTraffic.get();
long inTrafficSum=inTraffic.sum();
long i=inTrafficSum-inTrafficOld2;
inTrafficOld2 =inTrafficSum;
inSpeedAvg2= (long) (i*1000000000.0/d);
}
if(outTraffic!=null) {
long o=outTraffic.get()-outTrafficOld2;
outTrafficOld2 =outTraffic.get();
long outTrafficSum=outTraffic.sum();
long o=outTrafficSum-outTrafficOld2;
outTrafficOld2 =outTrafficSum;
outSpeedAvg2= (long) (o*1000000000.0/d);
}
if(inCounter!=null) {
long i=inCounter.get()-inCounterOld2;
inCounterOld2 =inCounter.get();
long inCounterSum=inCounter.sum();
long i=inCounterSum-inCounterOld2;
inCounterOld2 =inCounterSum;
inPPSAvg2= (long) (i*1000000000.0/d);
}
if(outCounter!=null) {
long o=outCounter.get()-outCounterOld2;
outCounterOld2 =outCounter.get();
long outCounterSum=outCounter.sum();
long o=outCounterSum-outCounterOld2;
outCounterOld2 =outCounterSum;
outPPSAvg2= (long) (o*1000000000.0/d);
}
}
@@ -275,7 +288,7 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
public String toString() {
StringBuilder sb=new StringBuilder(super.toString());
sb.append('\t');
sb.append(bytesUnit(outTraffic.get())).append("\t").append(bytesUnit(inTraffic.get())).append("\t").append(bytesUnit(outSpeed)).append("/s\t").append(bytesUnit(inSpeed)).append("/s\t");
sb.append(KLALBUtils. convertIBUint(outTraffic.sum())).append("\t").append(KLALBUtils.convertIBUint(inTraffic.sum())).append("\t").append(KLALBUtils.convertIBUint(outSpeed)).append("/s\t").append(KLALBUtils.convertIBUint(inSpeed)).append("/s\t");
/*if(getState()==OFFLINE) {
sb.append((coolingTime-(System.currentTimeMillis()-mls))/1000L);
@@ -298,8 +311,8 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
private volatile AtomicLong inCounter=new AtomicLong();
private volatile AtomicLong outCounter=new AtomicLong();
private volatile LongAdder inCounter=new LongAdder();
private volatile LongAdder outCounter=new LongAdder();
private long inCounterOld;
private long outCounterOld;
@@ -333,23 +346,23 @@ public class SpeedAndTrafficMonitorDataImpl extends MonitorDataImpl implements S
}
@Override
public AtomicLong getInPacketCounterAL() {
public LongAdder getInPacketCounterAL() {
return inCounter;
}
@Override
public AtomicLong getOutPacketCounterAL() {
public LongAdder getOutPacketCounterAL() {
return outCounter;
}
@Override
public long getInPacketCounter() {
return inCounter.get();
return inCounter.sum();
}
@Override
public long getOutPacketCounter() {
return outCounter.get();
return outCounter.sum();
}
public double getOutPPSMax2() {
@@ -0,0 +1,156 @@
package org.kne.cloud.network.monitor;
import org.kne.cloud.clock.HighAccuracyClock;
import org.kne.math.Long128;
/**
* 时间戳监控器接口
* 提供高性能的数据包监控和流量统计功能
*/
public interface TimestampMonitor<K> {
// ==================== 配置相关方法 ====================
/**
* 获取监控器名称
*/
String getName();
/**
* 设置监控器名称
*/
void setName(String name);
/**
* 获取时钟源
*/
HighAccuracyClock getClock();
// ==================== 数据记录方法 ====================
/**
* 记录数据包(使用当前时间)
* @param key 数据包标识
* @param length 数据包长度
* @return 是否记录成功
*/
boolean recordPacket(K key, int length);
/**
* 记录数据包(使用指定时间戳)
* @param key 数据包标识
* @param timestamp 时间戳
* @param length 数据包长度
* @return 是否记录成功
*/
boolean recordPacket(K key, Long128 timestamp, int length);
// ==================== 清理维护方法 ====================
/**
* 执行清理操作(使用当前时间)
*/
void cleanup();
/**
* 执行清理操作(使用指定时间)
* @param currentTime 当前时间
* @param timeWindowNs 时间窗口(纳秒)
*/
void cleanup(Long128 currentTime, long timeWindowNs);
// ==================== 统计查询方法 ====================
/**
* 计算数据量(使用当前时间)
* @param timeWindowNs 时间窗口(纳秒)
* @return 数据量(字节)
*/
long calculateDataVolume(long timeWindowNs);
/**
* 计算数据量(使用指定时间)
* @param currentTime 当前时间
* @param timeWindowNs 时间窗口(纳秒)
* @return 数据量(字节)
*/
long calculateDataVolume(Long128 currentTime, long timeWindowNs);
/**
* 计算数据包数量(使用当前时间)
* @param timeWindowNs 时间窗口(纳秒)
* @return 数据包数量
*/
long calculatePacketCount(long timeWindowNs);
/**
* 计算数据包数量(使用指定时间)
* @param currentTime 当前时间
* @param timeWindowNs 时间窗口(纳秒)
* @return 数据包数量
*/
long calculatePacketCount(Long128 currentTime, long timeWindowNs);
/**
* 计算带宽(使用当前时间)
* @param timeWindowNs 时间窗口(纳秒)
* @return 带宽(字节/秒)
*/
long calculateBandwidth(long timeWindowNs);
/**
* 计算带宽(使用指定时间)
* @param currentTime 当前时间
* @param timeWindowNs 时间窗口(纳秒)
* @return 带宽(字节/秒)
*/
long calculateBandwidth(Long128 currentTime, long timeWindowNs);
/**
* 计算流量统计信息(使用当前时间)
* @param timeWindowNs 时间窗口(纳秒)
* @return 流量统计信息
*/
TrafficStats calculateTrafficStats(long timeWindowNs);
/**
* 计算流量统计信息(使用指定时间)
* @param currentTime 当前时间
* @param timeWindowNs 时间窗口(纳秒)
* @return 流量统计信息
*/
TrafficStats calculateTrafficStats(Long128 currentTime, long timeWindowNs);
// ==================== 全局统计方法 ====================
/**
* 获取总数据量(从启动开始)
* @return 总数据量(字节)
*/
long getTotalDataSize();
/**
* 获取总数据包数量(从启动开始)
* @return 总数据包数量
*/
long getTotalPackets();
/**
* 获取当前条目数量
* @return 条目数量
*/
int getEntryCount();
// ==================== 管理控制方法 ====================
/**
* 重置监控器(清空所有数据)
*/
void reset();
/**
* 获取字符串表示
* @return 监控器状态字符串
*/
String toString();
}
@@ -0,0 +1,31 @@
package org.kne.cloud.network.monitor;
public class TimestampMonitorKey<K> {
private final K key;
private final long sequence;
public TimestampMonitorKey(K key, long sequence) {
this.key = key;
this.sequence = sequence;
}
public K getKey() { return key; }
public long getSequence() { return sequence; }
@Override
public int hashCode() {
return 31 * key.hashCode() + (int) (sequence ^ (sequence >>> 32));
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof TimestampMonitorKey)) return false;
TimestampMonitorKey<?> other = (TimestampMonitorKey<?>) obj;
return key.equals(other.key) && sequence == other.sequence;
}
@Override
public String toString() {
return "TimestampMonitorKey [key=" + key + ", sequence=" + sequence + "]";
}
}
@@ -0,0 +1,60 @@
package org.kne.cloud.network.monitor;
import java.math.BigInteger;
import org.kne.math.Long128;
public class TimestampMonitorValue implements Comparable<TimestampMonitorValue> {
private final Long128 timestamp;
private final int length;
private final TimestampMonitorKey<?> key;
public TimestampMonitorValue(TimestampMonitorKey<?> key, Long128 timestamp, int length) {
this.key = key;
this.timestamp = timestamp;
this.length = length;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + length;
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TimestampMonitorValue other = (TimestampMonitorValue) obj;
if (length != other.length)
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
return true;
}
@Override
public String toString() {
return "TimestampMonitorValue [timestamp=" + timestamp + ", length=" + length + "]";
}
public Long128 getTimestamp() { return timestamp; }
public int getLength() { return length; }
public TimestampMonitorKey<?> getKey() { return key; }
@Override
public int compareTo(TimestampMonitorValue other) {
return this.timestamp.compareTo(other.timestamp);
}
}
@@ -0,0 +1,46 @@
package org.kne.cloud.network.monitor;
import org.kne.math.Long128;
/**
* 流量统计信息类
*/
public class TrafficStats {
public long packetCount;
public long totalBytes;
public Long128 earliestTimestamp;
public Long128 latestTimestamp;
public long timeWindowNs;
public Long128 currentTime;
public TrafficStats() {
this.packetCount = 0;
this.totalBytes = 0;
this.earliestTimestamp =Long128.ZERO;
this.latestTimestamp = Long128.ZERO;
this.timeWindowNs = 0;
this.currentTime = Long128.ZERO;
}
public long getPacketsPerSecond() {
return (long) (timeWindowNs > 0 ? (packetCount * 1e9) / timeWindowNs : 0.0);
}
public long getAveragePacketSize() {
return (long) (packetCount > 0 ? (double) totalBytes / packetCount : 0.0);
}
public long getBandwidth() {
return (long) (timeWindowNs > 0 ? (totalBytes* 1e9) / timeWindowNs : 0.0);
}
@Override
public String toString() {
return "TrafficStats [packetCount=" + packetCount + ", totalBytes=" + totalBytes + ", timeWindowNs="
+ timeWindowNs + ", getPacketsPerSecond()=" + getPacketsPerSecond() + ", getAveragePacketSize()="
+ getAveragePacketSize() + ", getBandwidth()=" + getBandwidth() + "]";
}
}