我用Spring Boot应用程序和NodeJS应用程序编写了一个非常基本的速度测试。我的NodeJS最高可以达到2.2Gbps,而我的Spring Boot应用程序最高可以达到550 Mbps。我在Spring Boot中尝试了两种不同的实现,它们的产生速度都相对相同。
实现1:(最高550 Mbps)
private long downloadDuration = 10000;
private int downloadChunkSize = 1024 * 1024;
@GetMapping("/test")
public void downloadTest(HttpServletResponse response) throws IOException {
OutputStream os = response.getOutputStream();
final byte[] bytes = getRandomChunk();
long endOn = System.currentTimeMillis() + downloadDuration;
while (System.currentTimeMillis() <= endOn) {
os.write(bytes, 0, downloadChunkSize);
}
os.close();
}
实施2 (最高500 Mbps)
@GetMapping("/test2")
public StreamingResponseBody downloadTest2() {
final byte[] bytes = getRandomChunk();
final long endOn = System.currentTimeMillis() + downloadDuration;
return new StreamingResponseBody() {
@Override
public void writeTo(OutputStream out) throws IOException {
while (System.currentTimeMillis() <= endOn) {
out.write(bytes);
}
}
};
}
使用NodeJS XHRRequest
,我可以轻松达到2.2 Gpbs。
知道我在做什么错吗?
供参考:
private byte[] getRandomChunk() {
final byte[] bytes = new byte[1024 * 1024];
ThreadLocalRandom.current().nextBytes(bytes);
return bytes;
}
以及NodeJS代码:
const requestHandler = (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
const startTime = new Date();
const endOn = new Date(startTime.getTime() + 10000);
const chunkSize = 1024 * 1024;
const chunk = 'a'.repeat(chunkSize);
const sendNext = () => {
response.write(chunk, undefined, () => {
if (new Date() <= endOn) {
sendNext();
} else {
response.end();
}
});
};
sendNext();
};
const testServer = http.createServer(requestHandler);
这是前端速度测试的最小工作示例:
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div id="speed" style="font-size: 41px;">0 Mbps</div>
<script type="text/javascript">
const url = 'http://localhost:3001';
const nThreads = 4;
const method = 'GET';
const speedLabel = document.getElementById('speed');
let totalDownloaded = 0;
let mainStart;
let totalElapsed = 0;
function download(i) {
let downloaded = 0;
const dl = new XMLHttpRequest();
dl.onload = function (e) {
console.log('[%d] Done', i);
dl.abort(); // Done, Empty RAM
};
dl.onprogress = function (e) {
const previousDownloaded = downloaded;
downloaded = e.loaded;
// Update global variables
totalDownloaded += downloaded - previousDownloaded;
totalElapsed = (performance.now() - mainStart) / 1000;
totalSpeed = 8 * (totalDownloaded / 1000000) / totalElapsed;
// Update UI
speedLabel.innerHTML = (totalSpeed) + ' Mbps';
};
dl.open(method, url + '?threadId=' + i + '&nocache=' + Math.round(Math.random() * 1000000000));
dl.send();
}
window.onload = function () {
mainStart = performance.now();
for (let i = 0; i < nThreads; i++) {
download(i);
}
};
</script>
</body>
</html>