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).