git archive
processes that started SSH processes to communicate with file servers. These requests constantly recorded gigabytes of data, and also transferred them through nginx. One simple idea was to order more servers, but this would create a duplicate cache of archived repositories. I wanted to avoid it, if possible. So, I decided to start over and rewrite the Nodeload from scratch. git archive
. Cached repositories are now recorded in the TMPFS section to reduce the load on the I / O subsystem. The Nodeload proxy server also tries to use file backup servers instead of active file servers, shifting most of the load to unloaded backup servers.write()
returns false. After receiving such a value, you can pause the proxied HTTP request flow until the response object generates a drain
event. The drain
event means that the response object is ready to send more data, and that you can now resume the proxied HTTP request stream. This logic is fully encapsulated in the ReadableStream.pipe()
method. // proxy the file stream to the outgoing HTTP response var reader = fs.createReadStream('some/file'); reader.pipe(res);
top
and ps
did not show that nodeload processes change their size. Nodeload processes worked well, but we observed that the available server memory was slowly decreasing in size.proxy_buffering
option. As soon as we turned it off, IO dropped sharply. This means that the streams run at the speed of the client. If clients cannot download the archive quickly enough, the proxy pauses the HTTP request flow. This is passed on to the archiver application, which pauses the file stream.This happened because the read streams were not properly closed when clients discontinued the download. This forced FD to remain open on the Nodeload server, as well as on the file servers. In fact, this led to the fact that nagios warned us about the overflow of the / data / archives partition when there were only 20 MB of archives. Open file descriptors prevented the server from using space from remote archive caches.tmm1 @ arch1: ~ $ sudo lsof -nPp 17655 | grep ": 7005 (" node 17655 git 16u IPv4 8057958 TCP 172.17.1.40:49232->172.17.0.148:7005 (ESTABLISHED) node 17655 git 21u IPv4 8027784 TCP 172.17.1.40 Boron8054- 172.17.0.133:7005 (ESTABLISHED) node 17655 git 22u IPv4 8058226 TCP 172.17.1.40:42498->172.17.0.134:7005 (ESTABLISHED)
close
event of the HTTP request object on the server. pipe()
does not actually handle this case, because it is written for a generic API readable stream. The “close” event is different from the more general “end” event, because the first event means that the HTTP request flow was terminated before response.end()
was called. // check to see if the request is closed already if (req.connection.destroyed) { return; } var reader = fs.createReadStream('/some/file'); req.on('close', function() { reader.destroy(); }); reader.pipe(res);
Source: https://habr.com/ru/post/125644/
All Articles