O Node.js sempre será mais lento que o Golang?

Há um sentimento de que, literalmente, toda semana, uma nova “estrutura da web” para o Node.js. aparece, chamada de algo que funciona mais rápido do que tudo o que veio antes. Todo mundo sabe que o Express é lento, mas a próxima estrutura é capaz de melhorar verdadeiramente o desempenho do subsistema de E / S Node.js. A única coisa que pode fazer é eliminar a carga excessiva no sistema criado pelo Express. Não se fala em melhorar algo fundamental. De fato, para melhorar radicalmente a situação, você precisa trabalhar em um nível mais profundo e não adicionar novas abstrações sobre o Node.js.

imagem

O que é necessário para criar aplicativos de servidor na plataforma Node.js. que executam muito mais rápido do que tudo o que é hoje?

Análise da situação


Express é uma das estruturas da Web mais antigas para o Node.js. Ele é baseado nos recursos padrão dessa plataforma, oferecendo aos desenvolvedores uma interface conveniente criada em torno do conceito do aplicativo e permitindo gerenciar rotas de URL, parâmetros, métodos e similares.

Express é simples: ajuda os programadores a desenvolver aplicativos rapidamente. A única coisa que lhe falta é desempenho. Projetos que aparecem constantemente, como o Fastify, esforçam-se para oferecer aos desenvolvedores os mesmos recursos que o Express, mas com menos perda de desempenho. Mas eles mesmos criam uma carga adicional no sistema e afetam gravemente o desempenho. Eles são severamente limitados pelo que a plataforma Node.js. pode fornecer. E pode dar, em comparação com os concorrentes, nem tanto.


O número de solicitações HTTP processadas por servidores diferentes por segundo

Preste atenção na linha vermelha. Esta é a plataforma máxima Node.js. Para ela, independentemente de seus nomes conterem a palavra "rápido" ou não, eles não são capazes de cruzar essa linha. Na verdade, esse é um limite de desempenho muito baixo ao comparar a plataforma Node.js. com suas alternativas populares, como a Golang.

Felizmente, o Node.js. suporta complementos em C ++, fichários do Google V8 que permitem vincular JavaScript e C ++, e permite chamar qualquer mecanismo do JavaScript, mesmo que esses mecanismos sejam fornecidos por algo diferente da plataforma Node.js.

Isso torna possível expandir e aprimorar os recursos dos aplicativos JavaScript, permitindo alcançar novos níveis de desempenho. Isso permite que os programas JavaScript espremam todo o possível do mecanismo Google V8, não se limitando ao que os desenvolvedores do Node.js consideraram suficiente.

Sobre o µWebSockets.js


No início deste mês, lancei um novo projeto - µWebSockets.js . O GitHub é usado como hospedagem para seu código, não o npm, mas você pode instalá-lo no Node.js usando o npm da seguinte maneira:

npm install uNetworking/uWebSockets.js#v15.0.0 

Para trabalhar com o µWebSockets.js, você não precisa de um compilador. Linux, macOS e Windows são suportados. A versão inicial do sistema é 15.0.0, a numeração de versões é realizada de acordo com as regras da versão semântica.

O µWebSockets.js é um servidor da Web alternativo para aplicativos de back-end escritos em JS. Consiste em cerca de 6 mil linhas de código C e C ++ e supera significativamente as melhores soluções escritas em Golang. Portanto, a troca bitfinex.com já portou ambas as APIs de negociação (REST e WebSocket) para µWebSockets.js e está gradualmente introduzindo-as em produção. Paolo Ardoino, da Bitfinex, observa que este é um ótimo projeto. Eu gostaria de dizer que o fato de ter tido a oportunidade de lançar o µWebSockets.js é inteiramente devido ao suporte fornecido pelo BitMEX, Bitfinex e Coinbase.

Recursos do µWebSockets.js


O µWebSockets.js é um novo projeto lançado sob a licença Apache 2.0, que é uma continuação do que é conhecido como "uws". Este projeto é uma pilha completa para o Google V8, iniciando no nível do kernel do sistema operacional, substituindo completamente os recursos padrão do Node.js. e representando um subsistema de E / S estável, seguro, compatível com os padrões, rápido e leve para o Node.js. A seguir, como é a interação do aplicativo JS com o sistema operacional usando o µWebSockets.js.


Interação do aplicativo JS com o SO usando o µWebSockets.js

Como você pode ver, o projeto consiste em várias camadas. Cada camada depende apenas da camada anterior. Essa arquitetura simplifica a identificação e correção de erros, bem como a implementação de trabalhos para expandir a solução devido à implementação de novos recursos.

Deve-se notar que a µSockets camada µSockets consiste em três subcamadas, que são mecanismos para trabalhar com eventos e com a rede, além de ferramentas para proteger dados. Isso permite, se necessário, substituir partes da solução, adicionar implementações alternativas de certos recursos ao sistema, sem encontrar a necessidade de alterar o código em um nível superior.

Por exemplo, se você precisar substituir o OpenSSL por algo, basta alterar o arquivo ssl.c com suas seiscentas linhas de código para o que você precisa. No entanto, outras camadas do sistema nem sabem o que é SSL. Essa abordagem, além da conveniência de substituir algumas partes do sistema por outras, também leva a uma simplificação do processo de detecção de erros.


OcketsSockets subcamadas internas

A arquitetura apresentada aqui é muito diferente da monolítica usada no Node.js, onde no mesmo arquivo de código-fonte você pode encontrar chamadas para o libuv, comandos para trabalhar com o sistema e chamadas para o OpenSSL e V8. No Node.js, tudo isso é misto, ninguém se propôs a isolar partes individuais dessa plataforma. Isso complica bastante o processo de fazer grandes alterações no Node.js.

Sobre o desenvolvimento de µWebSockets.js


Aqui está um exemplo extremamente simplificado e abreviado de trabalho com o µWebSockets.js, cuja principal tarefa é demonstrar os recursos básicos do sistema.

 /* SSL-   */ uWS.SSLApp({   key_file_name: 'misc/key.pem',   cert_file_name: 'misc/cert.pem',   passphrase: '1234' }).get('/hello', (res, req) => {   /*    */   res.end('Hello World!'); }).ws('/*', {   open: (ws, req) => {       console.log('A WebSocket connected via URL: ' + req.getUrl() + '!');   },   message: (ws, message, isBinary) => {       /* OK   false          *     */       let ok = ws.send(message, isBinary);   },   drain: (ws) => {       console.log('WebSocket backpressure: ' + ws.getBufferedAmount());   },   close: (ws, code, message) => {       console.log('WebSocket closed');   } }).listen(port, (token) => {   if (token) {       console.log('Listening to port ' + port);   } }); 

De certa forma, podemos dizer que o µWebSockets.js usando SSL pode ignorar o Gorilla WebSocket, uma implementação do protocolo WebSocket on Go, sem SSL. Ou seja, verifica-se que o código JS pode trocar mensagens usando SSL ainda mais rápido do que, sob certas condições, o código escrito em Ir sem SSL. Eu acredito que este é um excelente resultado.

Implementação rápida do protocolo WebSocket


O Socket.IO, de várias maneiras, pode ser considerado o equivalente ao Express em tempo real. Ambos os projetos surgiram há muito tempo, é fácil trabalhar com eles, eles são populares. Mas eles, entre outras coisas, também são lentos.


Várias implementações do WebSocket

As tarefas que o desenvolvedor do Socket.IO ajuda a resolver são reduzidas à implementação da funcionalidade de publicação e assinatura de mensagens, à capacidade de enviar e receber mensagens.

Ao mesmo tempo, vale ressaltar o uso de alguns mecanismos extras para trabalhar com o protocolo WebSocket, pois os navegadores há muito tempo suportam essa tecnologia. O tráfego SSL não pode ser interpretado por proxies corporativos, ele passa por eles da mesma maneira que qualquer tráfego HTTP; como resultado, o uso do protocolo WebSocket sobre SSL não bloqueia o tráfego correspondente. Podem ser fornecidos mecanismos de reposição para dar suporte ao WebSocket, mas não faz sentido usá-los. Eles apenas aumentam irracionalmente a complexidade das decisões.

Um dos objetivos do µWebSockets.js é oferecer aos desenvolvedores recursos semelhantes aos encontrados no Socket.IO para que o µWebSockets.js possa substituir completamente o Socket.IO sem a necessidade de invólucros de nível superior . Isso é possível se algum protocolo especial não padrão não for usado.

Muitas empresas têm problemas para publicar e assinar mensagens enquanto trabalham com o WebSocket. Deve-se observar que no release descrito do µWebSockets.js esses recursos não receberam muita atenção, mas agora um trabalho sério está sendo feito neles. O resultado será muito rápido (os testes mostram que o µWebSockets.js já é mais rápido que o Redis). Portanto, fique atento.

Sumário


Atualmente o µWebSockets.js está em desenvolvimento, novos recursos são adicionados ao projeto, os erros são corrigidos. Levará algum tempo para se livrar dessas pequenas falhas, características dos primeiros lançamentos de novos programas. Lembre-se de que este é um projeto grande que consiste em muitos milhares de linhas de código escritas em C e C ++, armazenadas em três repositórios. Aqui está o wrapper JavaScript - uWebSockets.js. Aqui está um servidor Web escrito em C ++ - uWebSockets. E aqui está a biblioteca base escrita em C - uSockets.

O projeto em questão é usado pelas empresas, os programas usados ​​para criar uma enorme carga nos subsistemas de E / S. Nessas empresas, estabilidade e segurança, que são completamente naturais e óbvias, são as características mais importantes do software que elas usam.

Caros leitores! Você planeja usar o µWebSockets.js em seus projetos?

Source: https://habr.com/ru/post/pt439976/


All Articles