BLOG | NGINX

NGINX como um proxy WebSocket

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Rick Nelson
Rick Nelson
Publicado em 16 de maio de 2014

O protocolo WebSocket fornece uma maneira de criar aplicativos web que suportam comunicação bidirecional em tempo real entre clientes e servidores. Parte do HTML5, o WebSocket torna muito mais fácil desenvolver esses tipos de aplicativos do que os métodos disponíveis anteriormente. A maioria dos navegadores modernos oferece suporte ao WebSocket, incluindo Chrome, Firefox, Internet Explorer, Opera e Safari, e cada vez mais estruturas de aplicativos de servidor também oferecem suporte ao WebSocket.

Para uso em produção empresarial, onde vários servidores WebSocket são necessários para desempenho e alta disponibilidade, é necessária uma camada de balanceamento de carga que entenda o protocolo WebSocket, e o NGINX oferece suporte ao WebSocket desde a versão 1.3 e pode atuar como um proxy reverso e fazer o balanceamento de carga de aplicativos WebSocket. (Todas as versões do NGINX Plus também oferecem suporte ao WebSocket.)

Confira os testes de desempenho recentes sobre a escalabilidade do NGINX para balancear a carga de conexões WebSocket.

O protocolo WebSocket é diferente do protocolo HTTP, mas o handshake WebSocket é compatível com HTTP, usando o recurso de atualização HTTP para atualizar a conexão de HTTP para WebSocket. Isso permite que aplicativos WebSocket se adaptem mais facilmente às infraestruturas existentes. Por exemplo, aplicativos WebSocket podem usar as portas HTTP padrão 80 e 443, permitindo assim o uso de regras de firewall existentes.

Um aplicativo WebSocket mantém uma conexão de longa duração aberta entre o cliente e o servidor, facilitando o desenvolvimento de aplicativos em tempo real. O mecanismo de atualização HTTP usado para atualizar a conexão de HTTP para WebSocket usa os cabeçalhos Upgrade e Connection . Existem alguns desafios que um servidor proxy reverso enfrenta ao oferecer suporte ao WebSocket. Uma delas é que o WebSocket é um protocolo hop-by-hop, então quando um servidor proxy intercepta uma solicitação de atualização de um cliente, ele precisa enviar sua própria solicitação de atualização para o servidor de back-end, incluindo os cabeçalhos apropriados. Além disso, como as conexões WebSocket são de longa duração, ao contrário das conexões típicas de curta duração usadas pelo HTTP, o proxy reverso precisa permitir que essas conexões permaneçam abertas, em vez de fechá-las porque parecem estar ociosas.

O NGINX oferece suporte ao WebSocket permitindo que um túnel seja configurado entre um cliente e um servidor de backend. Para que o NGINX envie a solicitação de atualização do cliente para o servidor de backend, os cabeçalhos Upgrade e Connection devem ser definidos explicitamente, como neste exemplo:

localização /wsapp/ { proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Atualização $http_upgrade;
proxy_set_header Conexão "Atualização";
proxy_set_header Host $host;
}

Uma vez feito isso, o NGINX lida com isso como uma conexão WebSocket.

Exemplo de NGINX WebSocket

Aqui está um exemplo ao vivo para mostrar o NGINX funcionando como um proxy WebSocket. Este exemplo usa ws , uma implementação WebSocket construída em Node.js . O NGINX atua como um proxy reverso para um aplicativo WebSocket simples utilizando ws e Node.js. Estas instruções foram testadas com o Ubuntu 13.10 e o CentOS 6.5, mas podem precisar ser ajustadas para outros sistemas operacionais e versões. Neste exemplo, o endereço IP do servidor WebSocket é 192.168.100.10 e o endereço IP do servidor NGINX é 192.168.100.20.

  1. Se você ainda não tiver o Node.js e o npm instalados, execute o seguinte comando:

    • Para Debian e Ubuntu:

      $ sudo apt-get install nodejs npm
    • Para RHEL e CentOS:

      $ sudo yum instalar nodejs npm
  2. O Node.js é instalado como nodejs no Ubuntu e como node no CentOS. O exemplo usa node , então no Ubuntu precisamos criar um link simbólico de nodejs para node :

    $ ln -s /usr/bin/nodejs /usr/local/bin/node
  3. Para instalar o ws , execute o seguinte comando:

    $ sudo npm instalar ws

    Observação:  Se você receber a mensagem de erro: “Erro: falha ao buscar no registro: ws”, execute o seguinte comando para corrigir o problema:

    $ sudo npm config set registro http://registry.npmjs.org/

    Em seguida, execute o comando sudo npm install ws novamente.

  4. O ws vem com o programa /root/node_modules/ws/bin/wscat que usaremos para nosso cliente, mas precisamos criar um programa para atuar como servidor. Crie um arquivo chamado server.js com este conteúdo:

    console.log("Servidor iniciado");
    var Msg = '';
    var WebSocketServer = require('ws').Server
    , wss = new WebSocketServer({port: 8010});
    wss.on('conexão', função(ws) {
    ws.on('mensagem', função(mensagem) {
    console.log('Recebido do cliente: %s', mensagem);
    ws.send('Servidor recebido do cliente: ' + mensagem);
    });
    });
  5. Para executar o programa do servidor, execute o seguinte comando:
    $ nó servidor.js
  6. O servidor imprime uma mensagem inicial "Servidor iniciado" e então escuta na porta 8010, aguardando que um cliente se conecte a ele. Ao receber uma solicitação do cliente, ele a ecoa e envia uma mensagem de volta ao cliente contendo a mensagem recebida. Para que o NGINX faça proxy dessas solicitações, criamos a seguinte configuração. Estamos adicionando o bloco de mapa para que o cabeçalho Connection seja corretamente definido como fechado quando o cabeçalho Upgrade na solicitação for definido como '' .

    http {
    mapa $http_upgrade $connection_upgrade {
    atualização padrão;
    '' fechar;
    }
    
    upstream websocket {
    servidor 192.168.100.10:8010;
    }
    
    servidor {
    ouvir 8020;
    localização / {
    proxy_pass http://websocket;
    proxy_http_version 1.1;
    proxy_set_header Atualização $http_upgrade;
    proxy_set_header Conexão $connection_upgrade;
    proxy_set_header Host $host;
    }
    }
    }

    O NGINX escuta na porta 8020 e envia solicitações por proxy para o servidor WebSocket de backend. As diretivas proxy_set_header permitem que o NGINX manipule corretamente o protocolo WebSocket.

  7. Para testar o servidor, executamos o wscat como nosso cliente:

    $ /root/node_modules/ws/bin/wscat --conectar ws://192.168.100.20:8020

    O wscat se conecta ao servidor WebSocket por meio do proxy NGINX. Quando você digita uma mensagem para o wscat enviar ao servidor, você a vê ecoada no servidor e então uma mensagem do servidor aparece no cliente. Aqui está um exemplo de interação:

    Servidor: Cliente:
    $ nó servidor.js
    Servidor iniciado
     
     
     
     
     
    wscat --conectar ws://192.168.100.20:8020
    Conectado (pressione CTRL+C para sair)
    > Olá
    Recebido do cliente: Olá
    < Servidor recebido do cliente: Olá

    Aqui vemos que o cliente e o servidor conseguem se comunicar por meio do NGINX, que atua como um proxy, e as mensagens podem continuar sendo enviadas e recebidas até que o cliente ou o servidor se desconecte. Tudo o que é necessário para que o NGINX manipule corretamente o WebSocket é definir os cabeçalhos corretamente para manipular a solicitação de atualização que atualiza a conexão de HTTP para WebSocket.

Leitura adicional


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."