When I read the Node HTTP module documentation, I noticed the server.timeout property. I wanted to introduce it briefly, but after sorting it out, I found that there is a huge content supporting timeout: server.timout -> node core timers -> uv timers -> linux msleep/hrtimer -> clocksource -> tsc -> cmos rtc -> clock After the end of the timer series, Noder can roughly understand: How clock cycle drives Linux msleep/hrtimer; The relationship between Linux timers and UV timers; Relationship between Node timers and UV timers.

As mentioned in the previous article, users may encounter socket hang up and connect ECONNREFUSED when requesting services, and timer is used as resource protection measures. This article will describe the timeout problems of the server and client.

Timeout parameter

In the CS architecture, there are about three interfaces where users can programmatically set the entry to a network-related timeout.

  • Nodejs layer: Server and client

  • Operating system layer: Socket

The Server side

const server = http.createServer();
server.timeout(60000)
Copy the code

The Client side

const request= https.request();
request.setTimeout(60000);
Copy the code

Socket read/write (socket has connect timeout, but not directly exposed)

setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); / / by optname = SO_RCVTIMEO | SO_SNDTIMEO to set the maximum time of the socket send and receive data, if not setCopy the code

The three relations

Both Server and Clinet realize network communication through system call socket. The most intuitive feeling is that the timeout parameter of Server and client is passed to the socket system call. Then, has timeout finally been converted into setSocketopt parameter? This problem can be solved in two directions: the Bindings layer and the Internal Module layer.

Bindings layer

Nodejs relies on Libuv to implement network communication. The easiest way to verify this problem is to check whether the Bindings layer calls libuv methods. Set the socket timeout by exposing the uv__socket_sockopt method in libuv, and then searching the node/ SRC source directory for uv__socket_sockopt without any calls, so all three are clean.

Internal module layer

Tracing the timeout parameter call chain from the server side is HTTP -> _http_server -> NET -> stream_base_common -> timer.setunrefTimeout.

Tracing the timeout parameter call chain from the client side is HTTP -> _http_client -> NET -> stream_base_common -> timer.setunrefTimeout.

It can be found that both parties use the timer of NodeJS itself, which has nothing to do with setsocket, so the three parties are innocent.

Not white

It can be seen from the above that timeout of the three are clean and non-polluting, but they are interrelated and affect each other. To figure out the relationship between the three parties, we must first figure out the three representatives: socket, request and response.

Take the server as an example. The socket represents a connection between the client and the server. Request Indicates the client request of the connection. Response Indicates the server response for this connection.

  1. All threeRegister separatelyThe timeout
  2. The timeout callback of the socket doesTriggering the Timeout event, causing req and RES to trigger timeout

plainly

As can be seen from the above, socket timeout plays a key role in the whole process, so it is necessary to make clear the socket timeout process

Counterclockwise flow

The gray line represents the listen process, which registers TCP handlers into libuv’s event loop.

The purple line represents a connection process that injects the socket into a callback and registers the socket with a callback function that destroys the socket.

SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc OnConnection: SRC /connection_wrap.cc

And do not set

As a means of resource protection, Timer is widely used, but there is no free lunch, Timer has a cost, set or not set, how much?

Nodejs programming requires constant attention to garbage collection. If timer is set, a large number of queue nodes need to be scanned for garbage collection in JS side. The Libuv and OS layers also maintain some timing related data structures; Too many timed interrupts also have some performance overhead in the code (weak, JS only has low precision timers).

The server in Nodejs is not set by default, so sockets are long links, which may cause security problems.

Set different policies according to different application scenarios. For example, internal systems can consider not setting, or setting a long timeout(NodeJS services are usually not directly exposed, often have multiple front-layers, and the timeout parameter can be set to the front-layer, such as nginx); External systems need to set a timeout for a relatively short time.

Abnormal condition

To this point about the timer summary is to come to an end, originally expected to write a week, but an carelessly, timeout. So, timeout is normal, not timeout is abnormal.

Follow my wechat official account “SUNTOPO WLOG”, welcome to leave a comment and discuss, I will reply as much as possible, thank you for reading.