I'm writing a network monitoring utility that runs as a Node.js app in a Linux container running on Kubernetes. The utility uses Node's net.Socket to periodically (every 30 seconds) create a TCP socket to a set of URIs (https://random URI.org, for example). After a return from a call to the connect()
method, I measure how long the connection took to establish, log this information, and then close the socket with destroy()
.
Everything runs fine (with sockets taking about 30 ms to establish) but occasionally (~once every other minute or so), establishment of the socket will take > 4000 ms.
To remove Node.js from the picture, I ran nping on the Linux pod itself, to the same URI, and did not see this behavior (I did see the occasional slow ping, but these were about 1000 ms).
Any idea if I'm doing something wrong, or could this just be an issue with Node's net library?
const client: net.Socket = new net.Socket();
const stopwatch: Stopwatch = new Stopwatch();
stopwatch.start();
// Wrapping net.Socket.connect in a promise so that we can await
// until we have results from the TCP socket fired
await new Promise((resolve, reject) => {
// Register event handlers
client.on('connect', () => {
tcpSuccess = true;
tcpLatency = this.calculateLatencyAndCleanup(client, stopwatch);
resolve();
});
client.on('error', (err) => {
tcpLatency = this.calculateLatencyAndCleanup(client, stopwatch);
reject('Socket error for: `' + hostString + ':' + tcpPort + '`');
});
client.on('timeout', () => {
tcpLatency = this.calculateLatencyAndCleanup(client, stopwatch);
reject('Socket timeout for: `' + hostString + '`');
});
// Attempt to create TCP socket
client.connect(tcpPort, hostString);
P.S. the call to clinet.destroy is in the calculateLatencyAndCleanup
method.