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.
- All three
Register separately
The timeout - The timeout callback of the socket does
Triggering 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.