javascript - Nginx node.js express preuzimanje velikih datoteka zaustavlja se na 1.08GB
Imam ovu Node.js aplikaciju koju proxyja Nginx (na produkciji). Jedna ruta je nešto poput ove:
exports.download = function(req, res){
var id = req.params.id;
if (id && id == 'latest')
{
res.download(config.items.release_directory+'/<1.6GB-file>.zip', function(err){
if (err) {
console.log(err);
} else {
// do something
}
});
}
else
{
res.redirect(301, '/');
}
};
Dakle, klikom na pravi put/URL preglednik počinje preuzimati veliku datoteku, ali zatim uvijek stane na 1,08 GB (datoteka je oko 1,6 GB), skraćujući je.
Zaista ne mogu razumjeti zašto. Imate li kakvih ideja?
UREDI: config.items.release_directory je statički Express direktorij deklariran kao:
app.use('/releases', express.static(path.join(__dirname, '..', 'releases')));
EDIT2: Na razvoju s gruntom koji izravno servira aplikaciju bez Nginxa, radi bez problema.
RIJEŠENO: pročitajte komentare dolje, problem je varijabla proxy_max_temp_file_size u Nginxu
Odgovor #1
Ovdje je u pitanju konfiguracija nginx-a, a ne nodejs kod.
nginx zapisuje privremene datoteke na disk prije nego što ih pošalje klijentu, često je dobra ideja onemogućiti ovu predmemoriju ako će stranica posluživati velike statične datoteke, nečim poput:
location / {
proxy_max_temp_file_size 0;
}
(bez ograničenja)
Odgovor #2
Snažno održavam postavljanje proxy_max_temp_file_size 0 jer će to imati učinak uklanjanja bilo kojeg proxy međuspremnika za sve vaše krajnje točke.
To znači da vaš poslužitelj aplikacija neće moći isprazniti podatke odgovora u NGINX predmemoriju (iz koje klijent nizvodno može čitati kad god dobije dovoljno povezanosti) i biti oslobođen/odblokiran. Umjesto toga, vaš poslužitelj aplikacija će čekati da klijent (bez NGINX proxyja u sredini) preuzme podatke.
Alternativno, možete uputiti svoj NGINX proxy da selektivno ne međuspremi podatke odgovora prilikom streamanja vaših zip datoteka kako biste izbjegli moguće probleme s popunjavanjem privremene datoteke međuspremnika NGINX-a i prekidom streamanja preuzimanja (što je moje iskustvo).
To možete postići tako da učinite nešto slično sljedećem u vašoj Node.js krajnjoj točki:
res.set('X-Accel-Buffering', 'no');
Na taj način podaci će se prenositi izravno iz Expressa do klijenata, ali samo za one krajnje točke za koje ne želite da se podaci odgovora pohranjuju u međuspremnik (najvjerojatnije vaša krajnja točka za streaming).
