Desenvolvendo aplicativos móveis com Node.js e MongoDB, parte 1: Os métodos e resultados de uma equipe

Acelerando o tempo de retorno dos sistemas de engajamento

Explore as vantagens de usar o Node.js (JavaScript do lado do servidor) para desenvolver sistemas de engajamento. Neste artigo, veja os resultados obtidos por uma equipe do IBM Extreme Blue que usou o Node e o MongoDB com o IBM Passes, um aplicativo que demonstra a noção de sistemas de engajamento. Sua experiência com Node e MongoDB fornece insights interessantes sobre o quão rápido o desenvolvimento de aplicativos pode ser realizado com essas soluções que estão começando a surgir na empresa. Caso decida prosseguir com o Node e o MongoDB, consulte a Parte 2 desta série, que fornece detalhes de instruções e melhores práticas para produção do Node.

Atualização em 26 de novembro de 2013: Foi incluída clareza adicional sobre o uso do Node.js na empresa, juntamente com o Java, como uma plataforma de aplicativo corporativo.

Atualização em 05 de setembro de 2013: Encontre mais informações sobre as escolhas de tecnologia dos autores e a abordagem do teste de desempenho, em resposta ao feedback de leitores.

Zach Cross, IBM Extreme Blue intern, IBM

Author photo - Zach CrossZach Cross é bacharel em Ciência da Computação pela Universidade da Carolina do Norte (UNC) em Chapel Hill. Atualmente, ele está cursando uma pós-graduação em Ciência da Computação na UNC. Seu conhecimento encontra-se em sistemas e engenharia de software, especialmente em protocolos de rede. Ele também tem grande interesse em programação GPGPU e sistemas distribuídos. Em seu tempo livre, gosta de andar de bicicleta, ler e cozinhar. Ele concluiu um estágio do IBM Extreme Blue em agosto de 2013.



Aga Pochec, IBM Extreme Blue intern, IBM

Author photo - Aga PochecAga Pochec possui dois Mestrados em Comércio Exterior da Warsaw School of Economics e do prestigioso Programa Community of European Management Schools and International Companies (CEMS) na Europa. Atualmente, ela está concluindo seu Mestrado em Administração de Empresas na Harvard Business School em Boston e é estagiária do Extreme Blue na IBM. Aga é uma gerente de projetos experiente com mais de cinco anos prática em consultoria e business intelligence abrangendo a Europa e Ásia-Pacífico. Seu conhecimento encontra-se em desenvolvimento de negócios, estratégia e marketing. Ela adora viajar e explorar novas culturas e culinárias em seu tempo livre. Ela concluiu um estágio do IBM Extreme Blue em agosto de 2013.



Daniel Santiago, IBM Extreme Blue intern, IBM

Author photo - Daniel SantiagoAtualmente, Daniel Santiago é estudante de engenharia da computação na Universidade de Porto Rico, Mayagüez. Ele é apaixonado por programação e tem interesse no desenvolvimento da web, backend e móvel. Daniel gosta de trabalhar com tecnologias emergentes como Node.js e MongoDB. Em seu tempo livre, gosta de cozinhar, correr e montar computadores para jogos. Ele concluiu um estágio do IBM Extreme Blue em agosto de 2013.



Divit Singh, IBM Extreme Blue intern, IBM

Author photo - Divit SinghAtualmente, Divit Singh é aluno de graduação na Virginia Tech, cursando bacharelado em Ciência da Computação. O conhecimento dele encontra-se em tecnologias móveis, visto que ele trabalha com a PhoneGap e com a Sencha Touch para criar aplicativos multiplataforma. Ele gosta de desenvolver aplicativos e é um desenvolvedor publicado na Google Play Store, bem como no GitHub. Ele também gosta de trabalhar com tecnologias da web emergentes como Node.js. Ele passa seu tempo livre praticando esportes, tocando música e jogando videogames. Ele concluiu um estágio do IBM Extreme Blue em agosto de 2013.



25/Abr/2014

O desenvolvimento de nuvem e móvel mudaram drasticamente a maneira como as empresas operam e se conectam com os clientes. As empresas cada vez mais buscam soluções de backend que sejam fáceis de escalar, prontas para implementações de nuvem e móveis e rapidamente produzidas.

Embora o Java ainda seja o padrão para o desenvolvimento de aplicativos corporativos e nuvem, há uma forte pressão no setor para reduzir a quantidade de alternância de contexto ao desenvolver aplicativos. Com os conceitos de design do MobileFirst na liderança, os desenvolvedores estão começando com uma abordagem “de fora para dentro” do desenvolvimento. Em virtude de o design “de fora para dentro” começar com o usuário, a interface com o usuário está proeminentemente à frente. Uma das bases para o desenvolvimento de UIs é o JavaScript. Ao poder começar com o JavaScript no cliente e, em seguida, ser capaz de reutilizar essas mesmas qualificações em JavaScript no servidor (tanto o Node.js como o MongoDB são baseados em JavaScript), há uma redução significativa na quantidade de alternância de contexto entre as diversas linguagens de programação que o desenvolvedor precisa compreender. Com os pesos-pesados do mercado como Walmart, General Motors e LinkedIn abertamente adotando e defendendo o Node, o Node.js parece ir com força total para a empresa, juntamente com o Java, como uma plataforma de aplicativo corporativo.

Sobre a equipe do IBM Extreme Blue

O programa Extreme Blue é o programa de estágio da IBM para estudantes talentosos buscando diplomas de MBA e desenvolvimento de software. Saiba mais em ibm.com/extremeblue.

A equipe do Extreme Blue do laboratório da IBM em RTP, NC, foi desafiada a desenvolver um backend completo no Node.js para o IBM Passes. A equipe o desenvolveu com sucesso em 40% menos de tempo do que o exigido por uma solução Java alternativa, oferecendo a mesma funcionalidade. Ela também realizou testes de desempenho abrangentes que demonstraram a escalabilidade mais fácil e a melhor utilização de hardware do backend do Node.js (em comparação com o Java).

Esse artigo apresenta os principais recursos e vantagens do Node.js usado com o MongoDB. Você aprenderá sobre os tipos de soluções mais adequados para a produção do Node.js, bem como as vantagens e desvantagens dela.

Desenvolvedores familiarizados com os conceitos básicos dos serviços da web RESTful, JSON, JavaScript e Node.js aproveitarão ao máximo esse artigo.

 

IBM Passes

IBM Passes é uma solução desenvolvida com base no Apple Passbook, que foi lançado pela Apple no final de 2012. O Apple Passbook é um aplicativo que permite que os usuários convenientemente armazenem em um lugar cartões de embarque, ingressos de cinema, cupons de varejo, cartões de fidelidade e outros materiais para o engajamento do cliente (chamados de passes). A Apple lançou o aplicativo juntamente com especificações para os passes. No entanto, ela não forneceu uma forma de as empresas criarem e gerenciarem esses passes. IBM Passes resolve esse problema. Ele contém um serviço da web RESTful que fornece uma API que outros aplicativos podem consumir. Esse serviço interage com o Push Notification Service da Apple por meio do IBM PushWorks e lida com a analítica usando o IBM WebSphere® Analytics Platform.

A IBM criou um frontend para esse serviço, que permite que os usuários criem, atualizem e distribuam passes. Esse frontend é chamado de Pass builder, mostrado na Figura 1. O Pass builder é uma solução HTML/JavaScript que se baseia na interface RESTful do backend do Passes. Para encontrar mais informações sobre o Pass builder, consulte a introdução abrangente ou a introdução breve e o vídeo.

Figura 1. Interface do IBM Pass builder

A implementação atual do backend do IBM Passes usa servlets Java para acessar o DB2. Com essa solução, os documentos JSON são armazenados como sequências de caracteres no banco de dados relacional do DB2. Isso requer a serialização e a desserialização de todas as transações que envolvem esses documentos JSON e leva a uma sobrecarga adicional. Além disso, as propriedades de consulta desses documentos se tornam mais complexas na medida que o aninhamento fica mais profundo.


Uma alternativa ao Java: uma pilha de tecnologia do Node.js e MongoDB

Uma observação sobre nossas escolhas de tecnologia

A equipe responsável pelo aplicativo IBM Passes original inicialmente considerou usar o Node.js e o MongoDB para ele. No entanto, por diversos motivos além do escopo desse artigo, eles ficaram presos às plataformas de desenvolvimento corporativo mais tradicionais (Java EE e um banco de dados SQL) para o backend.

Nosso projeto estava focado em uma implementação alternativa do backend RESTful para a solução IBM Passes. Nós usamos uma pilha de tecnologia completamente diferente: Node.js e MongoDB. Isso nos permitiu substituir a implementação de Java ainda mantendo o suporte ao cliente de frontend. Nossa implementação fornece o mesmo conjunto de APIs que a implementação de Java. Como resultado, ele é intercambiável como um backend para o cliente do Pass builder.

Além de recriar a funcionalidade da versão Java, realizamos testes de desempenho abrangentes nos dois aplicativos. Além disso, a pilha de tecnologia que usamos nos permitiu implementar as funcionalidades principais no tempo de desenvolvimento de três semanas em comparação com as cinco semanas da equipe do Java (40% de redução no tempo de retorno). Optamos por usar essa pilha de tecnologia por diversos motivos:

  • Especificação do Apple Passbook (estritamente JSON)
  • Serviço da web RESTful com o JSON sendo o formato de troca de dados primário
  • JavaScript Everywhere (frontend, backend e armazenamento de dados)

Por que escolhemos o Node.js

Vantagens do Node

O Node.js (Node) é um ambiente de E/S acionado por eventos escalável desenvolvido com base no tempo de execução JavaScript do Google Chrome—basicamente, uma implementação do lado do servidor do JavaScript. O Google V8 na verdade compila o JavaScript em código de máquina nativo antes da execução, resultando em um desempenho de tempo de execução extremamente rápido—algo normalmente não associado ao JavaScript. Desse modo, o Node permite que você desenvolva rapidamente aplicativos de rede extremamente rápidos e altamente simultâneos.

O Node é um tempo de execução de servidor da web JavaScript. Como ele usa JavaScript, os desenvolvedores do frontend podem trabalhar na mesma linguagem que os desenvolvedores do backend. Esse conceito é chamado de JavaScript Everywhere. Na prática, esse conceito unifica os esforços de desenvolvimento ao reduzir o número de diferentes conceitos que os desenvolvedores devem compreender. Além disso, o formato de troca de dados mais usado, JSON, pode ser analisado de forma nativa pelo frontend e pelo backend. Essa é outra maneira em que a sobrecarga de processamento pode ser reduzida por meio da simplificação da serialização. Além do benefício de usar uma linguagem de script, o ambiente de execução leve do Node permite o desenvolvimento e implementação rápidos. Como resultado, o Node é uma solução eficiente para o desenvolvimento ágil, em que a iteração normalmente envolve trabalhar em fatias verticais.

Tablela 1. Principais conceitos de tecnologia usados para o IBM Passes
Frontend do Pass builderBackend do Passes
JavaScriptJava
Node.jsContêiner do Servlet
MongoDBDB2
JSONSQL
JSON

O Node contém recursos que suportam as cargas de trabalho da web moderna: trocas de dados estruturados pequenas e frequentes. Isso torna o Node perfeito para sistemas de engajamento. Em outras palavras, ele é um candidato ideal para aplicativos que envolvem trocas de informações em vez de processos computacionais. Do ponto de vista técnico, isso significa escolher o Node para aplicativos dependentes de E/S em vez de para os dependentes de CPU. IBM Passes é um exemplo perfeito de tal aplicativo. As únicas operações computacionalmente caras são a assinatura criptográfica e a compactação (zipar). O restante do aplicativo envolve a troca dos recursos de imagem e dados JSON.

O Node se diferencia da maioria dos tempos de execução de aplicativos da web na maneira que ele lida com a simultaneidade. Em vez de usar o encadeamento para obter a simultaneidade, o Node utiliza um loop acionado por eventos sendo executado em um único processo. O Node suporta um modelo assíncrono (sem bloqueio), enquanto tecnologias como o Java suportam um modelo síncrono (com bloqueio). Para esclarecer as principais diferenças entre esses dois conceitos, considere a seguinte metáfora do restaurante:

Modelo assíncrono

Pense em um aplicativo da web como um restaurante e suas solicitações recebidas como os clientes fazendo pedidos. Um aplicativo assíncrono permitiria que um único garçom atendesse a vários clientes ao mesmo tempo. O garçom atenderia aos clientes conforme os pedidos fossem concluídos. No tempo de inatividade, o mesmo garçom cuidaria e novos pedidos dos clientes.

Modelo síncrono

Um “restaurante” síncrono dedicaria um único garçom a um único cliente do início até a conclusão de seu pedido. Como resultado, o restaurante precisa de uma quantidade de garçons igual à de clientes. Além disso, haveria momentos em que os garçons esperariam enquanto outro trabalho poderia ser realizado.

A diferença ilustrada por essa metáfora é simplesmente o mecanismo usado para obter a simultaneidade. O Java faz isso com encadeamentos, enquanto o Node usa um loop de eventos. O resultado é que o Java deve sofrer uma sobrecarga adicional na alternância de contexto entre os encadeamentos. Em outras palavras, mais encadeamentos significam mais tempo gasto comutando contextos e menos tempo trabalhando nas solicitações recebidas. Isso torna o ajuste de escala de um aplicativo Java mais caro.

O Node suporta E/S assíncronas, com base em eventos como a conclusão de uma operação de leitura de arquivo ou consulta de banco de dados. Esses eventos são tratados com funções de retorno de chamada, que permitem que o aplicativo prossiga enquanto a E/S está sendo realizada. O loop de eventos trata desses eventos. Para encontrar mais informações sobre o loop de eventos, consulte o “Node.js para desenvolvedores Java”, um artigo do developerWorks escrito por Andrew Glover.


Por que escolhemos o MongoDB

O MongoDB é um banco de dados orientado a documentos criado para facilitar o desenvolvimento e ajuste de escala. A capacidade de armazenar objetos JavaScript nativamente do MongoDB economiza tempo e energia de processamento. Em vez de uma linguagem específica de domínio como o SQL, o MongoDB utiliza uma interface JavaScript simples para realizar consultas. Consultar um documento é tão simples como passar um objeto JavaScript que descreve parcialmente o destino da pesquisa.

O MongoDB foi uma excelente solução para o nosso domínio do problema, porque, como mencionado, a especificação do Passbook da Apple é altamente dependente do JSON. Na verdade, os passes em si são descritos como objetos JSON. Como resultado, armazená-los como estão com o MongoDB é uma abordagem melhor que reduzir a estrutura JSON semicomplexa em várias relações em um banco de dados relacional (como o DB2).


Comparativo

Nossa abordagem para o teste de desempenho

A equipe (equipe do IBM Mobile Cloud Development e equipe do Extreme Blue) decidiu realizar uma comparação em vez de tentar atenuar os limites para realmente avaliar a pilha completa. Descobrimos que para as tecnologias baseadas em Java, não é fácil encontrar adaptadores para se comunicar com o MongoDB, semelhante à falta de adaptadores para o Node.js se comunicar com o DB2. Então pensamos que o tempo seria melhor utilizado mantendo a separação entre o antigo e o novo. O que também descobrimos é que as tecnologias normalmente seriam combinações de antigo + antigo ou novo + novo, então optamos por nos concentrar principalmente nesses pares.

Devido às restrições de tempo, houve dois pontos com os quais não pudemos trabalhar. Primeiro, alguns dos membros de nossa equipe são pessoas que trabalham com contêineres da web há bastante tempo, portanto teríamos gostado de ver os números de desempenho em um nível de pilha de chamada para indicar quais métodos eram os mais caros (tanto superficial como profundo) para obter uma visualização cumulativa e de baixa granularidade sobre o tempo gasto em cada método.

Quisemos comparar nossa implementação do Node do IBM Passes com sua versão Java. Decidimos comparar o desempenho de ponta a ponta dos dois aplicativos, com a métrica de interesse, em última análise, sendo os tempos de resposta das solicitações de HTTP realizadas para os diversos endpoints da API. O objetivo principal dessa abordagem era capturar o desempenho de toda a pilha por trás de cada solução. Ao considerar variáveis como rede e sistema operacional, obtivemos uma comparação objetiva dos dois aplicativos. Além disso, acreditamos que os tempos de resposta de ponta a ponta eram um reflexo melhor de uma experiência do usuário real do que uma análise mais granular como a cronometragem de consultas de bancos de dados ou a cronometragem de funções individuais.

Metodologia

Para fins de comparação dos dois aplicativos, escrevemos um wrapper do Node com base no Apache Benchmark, uma ferramenta de linha de comandos de comparação HTTP. A partir daí, criamos uma estrutura de comparação executada em relação a definições de teste genéricas e resultados gerados. O Apache Benchmark nos forneceu o tempo de resposta médio, seu desvio padrão, o número de solicitações concluídas por segundo, o número de respostas com falha (não 200), o número de erros do servidor e o número de tempos limite. Os parâmetros foram o nível de simultaneidade, o número de solicitações e a configuração da solicitação. Incluímos definições de teste e funções de configuração nessa estrutura e prosseguimos para a comparação de nosso aplicativo.

Cuidamos da parte dos conjuntos de ferramentas de nosso processo de comparação. O ambiente de teste é de igual, se não de maior, importância devido à abordagem científica desejada deste processo. Decidimos usar o OpenStack para imitar um ambiente de nuvem. Configuramos instâncias idênticas para o aplicativo Node, para o aplicativo Java e para o aplicativo de geração de carga. Cada instância recebeu um processador quad core de 2,4 GHz (virtual), 8 GB de RAM (virtual) e 80 GB de armazenamento. A Figura 2 mostra a topologia da implementação do OpenStack usada.

Figura 2. Topologia de implementação do OpenStack

Essas instâncias foram configuradas com a mesma imagem base (Ubuntu Server 12.04 64 bits). Além disso, foi instalado apenas o software necessário para executar e monitorar os aplicativos. No que se refere à configuração do tempo de execução, usamos a configuração padrão para o Node (a mesma em que o Chrome V8 Engine se baseia).

Consultamos a equipe do Java em relação à configuração do tempo de execução do JRE e usamos as configurações padrão para o contêiner do servlet e para o DB2. Nós reconhecemos que configurações adicionais poderiam potencialmente melhorar o desempenho do backend. No entanto, isso também é verdade para o tempo de execução do Node e perde a importância. Nosso propósito é provar que ele atende aos critérios de desempenho e pode ser escalado horizontalmente em vez de verticalmente, além de facilitar o desenvolvimento ágil.

As tarefas de comparação foram enfileiradas manualmente por meio da interface da web da instância do gerador de carga ou como resultado de alterações na base do código. A comparação prosseguiu no ambiente OpenStack. Definimos uma tarefa de comparação como a execução de todos os suítes de testes (como grupos de execuções de endpoint da API) considerando os parâmetros de nome da ramificação, nível de simultaneidade e total de solicitações a serem feitas. Dentro de uma comparação, um conjunto fixo de endpoints da API foi testado pela ferramenta de comparação. Esses testes foram executados sequencialmente (isto é, sem sobrepor o tráfego). Além disso, as comparações (grupos de testes) foram executadas sequencialmente pelo mesmo motivo.

Resultados

Nosso caso de teste demonstrou que a implementação do Node e do MongoDB apresentou tempos de resposta mais rápidos quando o nível de simultaneidade excedeu 50. Podemos atribuir isso à natureza dependente de E/S do aplicativo Passes. Abaixo do nível de simultaneidade de 50, o aplicativo Java foi mais rápido, pois o aplicativo foi degradado de dependente de E/S para dependente de CPU sob a carga reduzida. Com níveis de simultaneidade maiores, a instância única do Node claramente superou a instância Java/DB2 para todas as chamadas de API.

Figura 3. Resultados de desempenho (calculando os endpoints “mais rápidos” por aplicativo)

Para comparar a utilização de hardware da implementação do Node vs. de Java, foi necessário definir o perfil das instâncias em que os dois aplicativos estavam sendo executados. Para esse propósito, usamos dois aplicativos de coleta de estatística populares: CollectD e StatsD. A instalação do CollectD em nossas instâncias introduziu uma sobrecarga insignificante e tornou o uso de disco, memória e CPU transparente. Usamos o StatsD na instância de monitoramento para coletar essas estatísticas. O Graphite foi usado na mesma instância para visualizar os dados de séries temporais como gráficos apresentados em um formato de painel.

Pudemos correlacionar cada comparação com os dados de utilização de hardware das séries temporais. Embora tenhamos valores de uso médios para o uso de CPU e memória durante a comparação de cada endpoint, achamos mais útil mostrar as tendências gerais. A Figura 4 mostra essas métricas ao longo do período de tempo de uma comparação de longa duração. O aplicativo Node usou, em média, menos memória e uma porcentagem do CPU menor. O baixo uso de CPU pode ser interpretado como um resultado da natureza dependente de E/S do aplicativo.

Figura 4. Resultados de desempenho da comparação da utilização de hardware

Conclusões

Embora o Node possa não ser a panaceia para todos os desafios da web moderna, ele é perfeito para as demandas dos sistemas de engajamento. O Node foi projetado especificamente para aplicativos dependentes de E/S e trocas de informações frequentes. Seu ambiente de execução leve permite o desenvolvimento ágil e a iteração imediata. Como demonstrado em nosso caso de teste do IBM Passes, o Node levou a uma redução de 40% no tempo de retorno enquanto nos permitiu dobrar o tráfego atendido com metade dos servidores (em comparação com a implementação de Java). Dessa forma, o Node pôde fornecer as mesmas funcionalidades que o Java e superou o Java em termos de desenvolvimento rápido e melhor utilização de hardware.


Agradecimentos

Agradecimentos especiais para nossos mentores, cuja sabedoria e experiência nos orientaram durante nosso estágio: Joshua A. Alger, Andy Dingsor, Curtis M. Gearhart, Christopher Hambridge e Todd Kaplinger. Um enorme obrigado a Ross Grady, RTP Lab Manager do IBM Extreme Blue, cuja paciência e esforço para a melhoria contínua garantiu nosso sucesso. Gostaríamos também de expressar nossa gratidão a Jeff Jagoda por sua experiência em Node.js e inestimável feedback.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • Participe da comunidade do developerWorks : Entre em contato com colegas e especialistas enquanto explora os wikis, grupos, fóruns e blogs voltados aos desenvolvedores.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Desenvolvimento móvel, Tecnologia Java
ArticleID=969643
ArticleTitle=Desenvolvendo aplicativos móveis com Node.js e MongoDB, parte 1: Os métodos e resultados de uma equipe
publish-date=04252014