O arquivo de streaming NGINX e php_fpm leva o triplo na transferência?

1

Minha configuração: - nginx 1.0.6 (compilado do zero) - php 5.3.8 com php-fpm (também do zero).

Eu uso este script PHP para transmitir arquivos do site remoto para meus usuários:

        $chunksize = 1 * (1024 * 1024); //you may want to change this
        $bytes_send = 0;
        if ($file = fopen($file, 'rb',false)) {      
            while(!feof($file) &&  (!connection_aborted()) && ($bytes_send<$new_length)) {

                $buffer = fread($file, $chunksize);            
                echo ($buffer);                       
                flush();
                $bytes_send += strlen($buffer); 
            }
            fclose($file);                         
        } else {
            die('Error - can not open file.');
        }

depois que eu começo a baixar com minha conexão (20 Mbps), eu tenho esse resultado de ifstat

 eth0       
 KB/s in  KB/s out
 5105.77   1925.70
 5106.15   2063.77
 5083.80   2337.95
 4946.52   2487.28
 5127.37   2507.15
 5118.94   2474.98
 5172.55   2438.86
 4646.82   2451.87
 5246.18   2465.98
 5186.71   2459.66
 5032.03   2458.55

Isso é normal? O resultado no servidor de produção foi uma falha completa devido à falta de largura de banda: | no apache, o equilíbrio é par. Ajuda muito apreciada: /

@Edit Pequeno benchmark feito. Fazendo o download do arquivo de 500 MB por meio disso. Os resultados de cerca de 250-260 MBs foram assim e depois caíram para quase 0. Isso é algum tipo de equilíbrio de uso de rede que o nginx faz?

    
por Alex 26.09.2011 / 17:49

1 resposta

2

Isso acontece porque o nginx tenta ler o backend (php-fpm no seu caso) o mais rápido possível, armazenando em buffer a resposta primeiro na memória (limitada pelas configurações proxy_buffer_size e proxy_buffers ) e depois no disco ( até o tamanho especificado em proxy_max_temp_file_size , o padrão é 1 GiB). Portanto, o script "streaming" faz o download do arquivo o mais rápido possível, mesmo que a velocidade de download do cliente seja mais lenta.

Veja a documentação do módulo proxy nginx http - há vários parâmetros que podem ser ajustados e a maioria deles pode ser definida por local (para que você possa alterar o comportamento do buffer apenas para algumas URLs). Você pode até mesmo retornar o cabeçalho X-Accel-Buffering do back-end para desativar o buffer, ou melhor ainda, retorne o cabeçalho X-Accel-Redirect para fazer o nginx transmitir o arquivo sem vincular um processo de backend.

    
por 26.09.2011 / 18:57