优化代码,性能暴涨
This commit is contained in:
@@ -0,0 +1,476 @@
|
||||
package org.kne.cloud.network.perf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.channels.UnresolvedAddressException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import org.kne.cloud.clock.AdjustedNanoClock;
|
||||
import org.kne.cloud.network.MultipurposeSocketAddress;
|
||||
import org.kne.cloud.network.SpeedLimiter;
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.cloud.network.ipv6.IPv6Packet;
|
||||
import org.kne.cloud.network.ipv6.Inet6AddressGroup;
|
||||
import org.kne.cloud.network.klalb.ADDRPacket;
|
||||
import org.kne.cloud.network.klalb.ADDRREQPacket;
|
||||
import org.kne.cloud.network.klalb.BWINFPacket;
|
||||
import org.kne.cloud.network.klalb.IPv6OverKLALBPacket;
|
||||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||||
import org.kne.cloud.network.klalb.KLALBPacketLink;
|
||||
import org.kne.cloud.network.klalb.KLALBUtils;
|
||||
import org.kne.cloud.network.klalb.PINGPacket;
|
||||
import org.kne.cloud.network.klalb.PONGPacket;
|
||||
import org.kne.cloud.network.klalb.TESTPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRACKPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRPacket;
|
||||
import org.kne.cloud.network.klalb.VADDRREQPacket;
|
||||
import org.kne.cloud.network.monitor.MonitorData;
|
||||
import org.kne.cloud.network.monitor.QueueingMonitorDataImpl;
|
||||
|
||||
public class Kperf implements Runnable{
|
||||
|
||||
|
||||
|
||||
private ConcurrentLinkedQueue<KLALBPacket> IsendDequeList = new ConcurrentLinkedQueue<KLALBPacket>();
|
||||
|
||||
//private PriorityBlockingQueue<KLALBPacket> sendDequeList = new PriorityBlockingQueue<KLALBPacket>();
|
||||
|
||||
|
||||
private static final boolean debug = true;
|
||||
|
||||
private static final boolean showpacket = false;
|
||||
private volatile AdjustedNanoClock adjnc = new AdjustedNanoClock();
|
||||
private MultipurposeSocketAddress targetAddress;
|
||||
private MultipurposeSocketAddress bindAddress;
|
||||
private volatile boolean connected=false;
|
||||
private volatile KLALBPacketLink link;
|
||||
private QueueingMonitorDataImpl monitor=new QueueingMonitorDataImpl();
|
||||
|
||||
private volatile boolean closed = false;
|
||||
|
||||
private volatile Thread tlock;
|
||||
public Kperf(MultipurposeSocketAddress targetAddress,MultipurposeSocketAddress bindAddress) {
|
||||
Objects.requireNonNull(targetAddress);
|
||||
this.targetAddress=targetAddress;
|
||||
this.bindAddress=bindAddress;
|
||||
}
|
||||
public Kperf(MultipurposeSocketAddress targetAddress) {
|
||||
this(targetAddress,new MultipurposeSocketAddress("[::0]:0"));
|
||||
}
|
||||
public Kperf(KLALBPacketLink link) {
|
||||
Objects.requireNonNull(link);
|
||||
this.link=link;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private SpeedLimiter test = new SpeedLimiter(MIN_SPEED,10000000L);
|
||||
|
||||
private static long MIN_SPEED=64*1024L;
|
||||
private SpeedLimiter congress = new SpeedLimiter(0,10000000L);
|
||||
private long congressSpeed = 0;
|
||||
private double loadPercent = 1.01;
|
||||
|
||||
private volatile int testSize=0;
|
||||
//kperf {KLALB_Stream}[2486:1:34de:4abd:98c1:abd1:fc7a:401]:4564
|
||||
@Override
|
||||
public void run() {
|
||||
Thread tc = ThreadTool.makeVDaemonThreadIfSupport("测速控制线程", () -> {
|
||||
final int wtimes=5;
|
||||
System.out.println("测速开始!");
|
||||
try {
|
||||
long startTime;
|
||||
|
||||
/*System.out.println("测试1/4:延迟测试");
|
||||
test.setLimitspeed(0);
|
||||
startTime=System.nanoTime();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传延迟:%.3fms 下载延迟:%.3fms\n", monitor.getOutDelay()/1000000.0,monitor.getInDelay()/1000000.0);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
System.out.printf("上传延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getOutDelayMin()/1000000.0,monitor.getOutDelayAvg()/1000000.0,monitor.getOutJitter()/1000000.0);
|
||||
System.out.printf("下载延迟 最小:%.3fms 平均:%.3fms 抖动:%.3fms\n",monitor.getInDelayMin()/1000000.0,monitor.getInDelayAvg()/1000000.0,monitor.getInJitter()/1000000.0);
|
||||
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);*/
|
||||
|
||||
|
||||
startTime=System.nanoTime();
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试2/4:下载带宽测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=60000;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2()));
|
||||
}else {
|
||||
System.out.println("测试2/4:上传带宽测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=60000;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
|
||||
}
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
|
||||
|
||||
startTime=System.nanoTime();
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试3/4:上传带宽测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=60000;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getOutSpeedAvg()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
|
||||
|
||||
}else {
|
||||
System.out.println("测试3/4:下载带宽测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=60000;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载带宽:%s/s\n", KLALBUtils.bytesUnit(monitor.getInSpeedAvg()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
System.out.printf("下载带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getInSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getInSpeedMax2()));
|
||||
}
|
||||
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
startTime=System.nanoTime();
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试2/4:下载包转发率测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}else {
|
||||
System.out.println("测试2/4:上传包转发率测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
//System.out.printf("上传带宽 平均:%s/s 最大:%s/s\n",KLALBUtils.bytesUnit(monitor.getOutSpeedAvg2()),KLALBUtils.bytesUnit(monitor.getOutSpeedMax2()));
|
||||
}
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
startTime=System.nanoTime();
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("测试3/4:上传包转发率测试");
|
||||
test.setLimitspeed(1000L*1024L*1024L*1024L);
|
||||
testSize=0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("上传包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getOutPPS()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
}else {
|
||||
System.out.println("测试3/4:下载包转发率测试");
|
||||
test.setLimitspeed(0);
|
||||
testSize=0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
System.out.printf("%.2fs\t", (System.nanoTime()- startTime)/1000000000.0);
|
||||
System.out.printf("下载包转发率:%sPPS\n", KLALBUtils.defaultUnit(monitor.getInPPS()));
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("等待时间"+wtimes+"s");
|
||||
Thread.sleep(wtimes*1000);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("测速结束!");
|
||||
close();
|
||||
});
|
||||
try {
|
||||
monitor.setState(MonitorData.CONNECTING);
|
||||
if(link==null)
|
||||
link=KLALBUtils.createKLALBPacketLink(bindAddress, targetAddress,20000);
|
||||
|
||||
|
||||
link.setSoTimeout(20000);
|
||||
|
||||
|
||||
Thread t = ThreadTool.makeVDaemonThreadIfSupport("测速发送线程", () -> {
|
||||
tlock = Thread.currentThread();
|
||||
try {
|
||||
KLALBPacket kpp = null;
|
||||
|
||||
while ((!link.isClosed()) && (!closed)) {
|
||||
// TimeDebugger tdb=new TimeDebugger();
|
||||
// tdb.putTime("start");
|
||||
if(checkBandwidthReportTime()) {
|
||||
writePacketToKPL(new BWINFPacket(monitor.getOutSpeedAvg2(), monitor.getInSpeedAvg2()));
|
||||
}
|
||||
if (checkPingTimeSleep()) {
|
||||
writePacketToKPL(new PINGPacket(System.nanoTime()));
|
||||
|
||||
}else {
|
||||
KLALBPacket kpip = IsendDequeList.poll();
|
||||
if (kpip != null) {
|
||||
writePacketToKPL(kpip);
|
||||
|
||||
}else {
|
||||
|
||||
|
||||
if (test.checkTransmit(testSize+3)) {
|
||||
TESTPacket tp=new TESTPacket(testSize);
|
||||
writePacketToKPL(tp);
|
||||
|
||||
|
||||
|
||||
}else {
|
||||
LockSupport.parkNanos(1000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.yield();
|
||||
}
|
||||
} catch (IOException | UnresolvedAddressException e) {
|
||||
if (debug)
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
link.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
|
||||
boolean fst = true;
|
||||
while ((!link.isClosed()) && (!closed)) {
|
||||
KLALBPacket kpp = readPacketFromKPL();
|
||||
|
||||
if (kpp == null) {
|
||||
break;
|
||||
}
|
||||
switch (kpp.getType()) {
|
||||
case KLALBPacket.PING:
|
||||
sendIPacket(new PONGPacket(((PINGPacket) kpp).getTime() ,kpp.getRcvtime(), System.nanoTime()));
|
||||
break;
|
||||
case KLALBPacket.PONG:
|
||||
if (fst) {
|
||||
// coll.resetCoolingTime();
|
||||
|
||||
monitor.setState(MonitorData.ONLINE);
|
||||
connected=true;
|
||||
if(targetAddress!=null) {
|
||||
System.out.println("连接地址"+targetAddress+"成功!");
|
||||
}else {
|
||||
System.out.println("接受地址"+link.toString()+"连接成功!");
|
||||
}
|
||||
tc.start();
|
||||
fst = false;
|
||||
}
|
||||
|
||||
PONGPacket png = (PONGPacket) kpp;
|
||||
long ul = png.getRcvtime() - png.getTimepingsnd()-(png.getTimepongsnd()-png.getTimepingrcv());
|
||||
|
||||
long DsndDelayFactor0 = png.getTimepingrcv() - png.getTimepingsnd();
|
||||
long DrcvDelayFactor0 = png.getRcvtime() - png.getTimepongsnd();
|
||||
long DsndDelayFactor;
|
||||
long DrcvDelayFactor;
|
||||
|
||||
adjnc.getLock().lock();
|
||||
try {
|
||||
adjnc.calibrate(png.getTimepongsnd() + ul / 2 - png.getRcvtime(), ul / 2);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
if (DsndDelayFactor < 0) {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
|
||||
} else {
|
||||
adjnc.setDelta(adjnc.getDelta() + DsndDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
}
|
||||
} else {
|
||||
if (DrcvDelayFactor < 0) {
|
||||
adjnc.setDelta(adjnc.getDelta() - DrcvDelayFactor);
|
||||
DsndDelayFactor = DsndDelayFactor0 - adjnc.getDelta();
|
||||
DrcvDelayFactor = DrcvDelayFactor0 + adjnc.getDelta();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
adjnc.getLock().unlock();
|
||||
}
|
||||
|
||||
if (DsndDelayFactor >= 0 && DrcvDelayFactor >= 0) {
|
||||
monitor.setOutDelay(DsndDelayFactor);
|
||||
monitor.setInDelay(DrcvDelayFactor);
|
||||
monitor.setRecentPingNanoTime(png.getTimepingsnd());
|
||||
//pingInterval = monitor.getLatencyAvg()+2000000L;
|
||||
|
||||
//double load = 1 - monitor.getOutDelayMin() / (double) monitor.getOutDelay();
|
||||
loadPercent =Math.max( 1.2,0.4);
|
||||
}
|
||||
|
||||
LockSupport.unpark(tlock);
|
||||
break;
|
||||
case KLALBPacket.BWINF:
|
||||
BWINFPacket bwi = (BWINFPacket) kpp;
|
||||
if (bwi.getDownSpeed() >= congressSpeed) {
|
||||
congressSpeed = bwi.getDownSpeed();
|
||||
} else {
|
||||
congressSpeed = (congressSpeed * 999 + bwi.getDownSpeed()) / 1000;
|
||||
}
|
||||
congress.setLimitspeed(Math.max(MIN_SPEED,(long) (congressSpeed * loadPercent)) );
|
||||
// System.out.println(congressSpeed);
|
||||
break;
|
||||
case KLALBPacket.TEST:
|
||||
break;
|
||||
}
|
||||
Thread.yield();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if(monitor.getState()==MonitorData.CONNECTING)
|
||||
System.out.println("连接目标地址失败!");
|
||||
if(debug)
|
||||
e.printStackTrace();
|
||||
|
||||
}finally {
|
||||
monitor.setState(MonitorData.OFFLINE);
|
||||
if(link!=null) {
|
||||
try {
|
||||
link.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private volatile long time = System.nanoTime();
|
||||
private volatile long pingInterval = 10000000L;
|
||||
private volatile long pingIntervalSleep = 200000000L;
|
||||
|
||||
private boolean checkPingTime() {
|
||||
long cu = System.nanoTime();
|
||||
if (cu - time > pingInterval) {
|
||||
time = cu;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean checkPingTimeSleep() {
|
||||
long cu = System.nanoTime();
|
||||
if (cu - time > pingIntervalSleep) {
|
||||
time = cu;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private volatile long bwtime = System.nanoTime();
|
||||
private volatile long bwpingInterval = 10000000L;
|
||||
private volatile long bwpingIntervalSleep = 100000000L;
|
||||
private boolean checkBandwidthReportTime(){
|
||||
long cu = System.nanoTime();
|
||||
if (cu - bwtime > bwpingIntervalSleep) {
|
||||
bwtime = cu;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
closed = true;
|
||||
monitor.setState(MonitorData.OFFLINE);
|
||||
try {
|
||||
if (link != null)
|
||||
link.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*protected void sendPacket(KLALBPacket blk) {
|
||||
blk.markJoinqueuetime();
|
||||
sendDequeList.add(blk);
|
||||
LockSupport.unpark(tlock);
|
||||
}*/
|
||||
|
||||
private void sendIPacket(KLALBPacket blk) {
|
||||
IsendDequeList.add(blk);
|
||||
LockSupport.unpark(tlock);
|
||||
}
|
||||
|
||||
|
||||
private KLALBPacket readPacketFromKPL() throws IOException {
|
||||
KLALBPacket packet = link.readPacket();
|
||||
if (showpacket) {
|
||||
|
||||
System.out.println("RX:" + packet);
|
||||
}
|
||||
if (packet != null) {
|
||||
packet.putTimePassport("received");
|
||||
long length=packet.getLength();
|
||||
monitor.getInTrafficAL().addAndGet(length);
|
||||
monitor.getInPacketCounterAL().incrementAndGet();
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void writePacketToKPL(KLALBPacket packet) throws IOException {
|
||||
long length=packet.getLength();
|
||||
monitor.getOutTrafficAL().addAndGet(length);
|
||||
monitor.getOutPacketCounterAL().incrementAndGet();
|
||||
link.writePacket(packet);
|
||||
link.flush();
|
||||
packet.putTimePassport("sended");
|
||||
packet.printPassport();
|
||||
|
||||
if (showpacket) {
|
||||
System.err.println("TX:" + packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void startPerfing() {
|
||||
ThreadTool.makeVThreadIfSupport("测速接收线程" ,this).start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user