O proxy_buffering deve ser desativado no NGINX para suportar o Streaming SockJS XHR?

2

Eu tenho um aplicativo da web de "página única" que requer comunicação bidirecional entre o cliente e o servidor.

O aplicativo foi originalmente projetado para depender de WebSockets, mas foi modificado para usar o SockJS, com o suporte a WebSocket desativado.

Clientes, usando a biblioteca SockJS, tendem a usar "XHR Streaming" como meio de comunicação bidirecional.

O servidor é um aplicativo da Web Java, usando a implementação do Spring de um servidor SockJS (do módulo WebSocket do Spring), hospedado no Tomcat.

O NGINX é usado como um proxy reverso para o Tomcat.

A configuração padrão do NGINX é para que proxy_buffering seja ativado.

A documentação do NGINX não explica adequadamente o comportamento do buffer: não é óbvio sob quais circunstâncias o buffer seria liberado (ou seja, quando os dados seriam realmente enviados para o cliente) se os dados estiverem sendo transmitidos (do Tomcat) conexão HTTP de longa duração.

Minha observação é que os dados enviados do servidor (uma resposta à solicitação de um cliente) podem ficar no buffer do NGINX até que a próxima pulsação do SockJS gerada pelo servidor ocorra para esse cliente. O efeito disso é um atraso de 25 segundos transmitindo a resposta para o cliente!

Eu posso reproduzir esse problema de forma muito confiável por meio de experimentação - o comportamento é determinístico, mas não consigo explicar a relação entre o tamanho do buffer configurado, o tamanho dos dados sendo transmitidos e o comportamento do NGINX.

A responsabilidade do meu servidor é gerar respostas às invocações de comando dos clientes; cada resposta irá variar em tamanho (de alguns bytes a dezenas de kilobytes), mas é auto-suficiente.

O objetivo principal é reduzir a latência das respostas aos comandos do cliente.

O NGINX só vê um fluxo HTTP de longa duração; dividir o conteúdo do fluxo em respostas de comando individuais (para envio imediato) exigiria que o NGINX entendesse o protocolo proprietário do SockJS, o que não é possível.

Portanto, acredito que a política de buffer do NGINX é fundamentalmente incompatível com o meu caso de uso e planejo desativar proxy_buffering ; é assim?

A documentação do NGINX sugere que, se proxy_buffering estiver desabilitado, o servidor upstream (Tomcat) será forçado a manter a resposta HTTP aberta até que todos os dados tenham sido recebidos pelo cliente (o que parece ser uma definição razoável de buffering!). / p>

Consequentemente, a documentação do NGINX desaconselha a desabilitação de proxy_buffering , já que potencialmente desperdiçará recursos do servidor upstream.

No entanto, como meus clientes usam XHR Streaming, meu servidor já está para manter uma conexão HTTP aberta para cada cliente ativo (certo?). Portanto, desabilitar proxy_buffering não deve impactar negativamente o meu servidor Tomcat; está correto?

    
por wool.in.silver 12.07.2016 / 20:05

1 resposta

2

Acho que você está correto em seu raciocínio aqui. Eu tenho um aplicativo com a mesma configuração, sockjs por trás de um proxy nginx. Estávamos vendo muitas conexões abandonadas de um local com alta latência. Depois de encontrar esta postagem e desativar proxy_buffering , nossos problemas de conexões perdidas foram resolvidos.

Com base nos logs que eu estava vendo, acredito que o buffer nginx estava impedindo que algumas das mensagens fossem enviadas corretamente entre o cliente / servidor.

    
por 09.09.2016 / 22:14