O Google App Engine utilizava Apache Tomcat como seu webserver/servlet container, contudo posteriormente optou pelo Jetty. Essa decisão levou muitos na comunidade de desenvolvedores a questionar a mudança - teria algo de errado com o Tomcat? O InfoQ teve a oportunidade de entrevistar o time da Webtide, a empresa por trás do Jetty, afim de obter mais detalhes sobre a decisão.
InfoQ: Porque o Google escolheu o Jetty ao invés do Tomcat e muitos outros, para sua App Engine?
Os principais recursos que podem ter levado o Google a escolher o Jetty foi seu tamanho e flexibilidade. No cloud, tamanho é algo importante, isso porque se você estiver executando 10s de milhares de instâncias do Jetty (como o Google faz), então cada MB salvo por servidor significa 10s de GBs a menos de memória necessários (ou mais memória disponível para as aplicações).
O Jetty foi desenhado para ser plugável e extendido, o que tem permitido ao Google um alto nível de customização. Eles acoplaram o seu conector HTTP, o Google autenticador e o seu sistema de clusterização de sessão. De forma estranha, esses recursos permitem que o Jetty seja tão bom para a cloud computing, assim como pode ser utilizado de forma embarcada em dispositivos móveis como telefones e set top boxes.
InfoQ: O que faz do Jetty um eficiente servlet container em Java?
Quando desenvolvemos o Jetty, nós não o pensamos como um servidor de aplicação completo (embora o seja). Cada recurso é considerado plugável, logo se algo não é necessário, então não será carregado na memória e na cadeia de chamada do gerenciador de requisições. Se não deseja trabalhar com sessões, o processador de sessões pode ser removido, então nós não teremos o custo no ciclo para pesquisar por cookie de sessão. Quando você está lidando com milhões de requisições por segundo, até as mais simples pesquisas possuem custo elevado.
Nós não preocupávamos com o design voltado para a otimização do código e fizemos isso de modo gradual, a cada vez que alguém nos falava como as JVMs haviam melhorado em otimização e coleta de lixo. Acredite, um código bem legível pode ser otimizado e essa é a melhor maneira para se evitar a criação de objetos. Por exemplo, nós estamos usando modelos de concorrência em Jetty, mas nós não usamos muitos dos padrões de concorrência para estrutura de dados que instanciam muitos objetos. Por exemplo, ao invés de listas concatenadas concorrentes, nós usamos arrays circulares de lock concorrente duplo, com isso temos o benefício do não bloqueio de concorrência sem a criação de objeto.
InfoQ: O que faz do Jetty um excelente servidor para desenvolvedores (e para testes)?
O Jetty é utilizado em frameworks como GWT, scala/lift, grails, jruby e muitos outros. Então, se você usa essas tecnologias, você usa o Jetty "fora da caixa". O plugin jetty-maven é uma outra excelente ferramenta de desenvolvimento que permite aplicações web rodar sem a disponibilização de componentes em um arquivo war. Os arquivos de fonte podem ser editados e serem realizados os testes sem aguardar por um novo arquivo war. A natureza de embarcamento do Jetty permite ser simples escrever uma classe, que pode ser diretamente executada em sua IDE, debbuger e/ou profiler.
InfoQ: O que é inédito na maneira em que o Jetty trata as requisições cliente-servidor?
O Jetty é a 2a geração de servidores assíncronos. Nós fomos capazes de lidar com requisições assíncronas nesses 2 anos e isso faz parte do núcleo da nossa arquitetura. Outros containers adicionaram o suporte para servlets assíncronos, contudo penso que eles descobrirão que não é tão simples como se parece. Nosso engine HTTP assíncrono possui algo reutilizado em nosso cliente HTTP assíncrono, logo podemos escalonar a geração de requisições e o consumo das respostas.
Inclusive, assim como mencionamos anteriormente, nós tratamos requisições com um mecanismo extensível e plugável, que permite às funcionalidades de uma aplicação web serem omitidas, utilizadas e extendidas de forma individualizada.
InfoQ: Quais são os outros exemplos de uso do Jetty, sejam maiores ou menores?
A utilização pelo Zimbra/Yahoo mostra que o Jetty está rodando um servidor web de email para milhões de usuários. A inclusão no Eclipse IDE mostra que o Jetty roda em milhões de estações de desenvolvedores. O Jetty é utilizado pelo Hadoop (cluster map/reduce) que roda em milhares de nodos de clusters e possui o recorde mundial em ordenação da ordem de terabytes de dados. Nós também possuimos portabilidade para J2ME e compiladores nativos que permitem rodar em telefones móveis, roteadores domésticos e cartões Java! Conheça outros projetos que utilizam Jetty em http://docs.codehaus.org/display/JETTY/Jetty+Powered
InfoQ: E quais são os planos futuros para o Jetty?
No curto prazo, o objetivo é lançar a versão 7.0.0, para completar nossa mudança para o Eclipse Foundation. O Jetty 7 irá suportar muitas das funcionalidades do servlet 3.0, mas sem utilizar a nova API e requerendo o Java 1.6. Depois do Jetty 7, nós lançaremos o Jetty 8 com suporte ao serlvet 3.0 e o Java 1.6. O Jetty continuará inovando e seguindo as tendências da Web 2.0. Estamos incluindo no Firefox 3.5 o suporte ao cross domain do Ajax e utilizá-lo no Cometd. Nós também iremos incluir o suporte ao WebSocket e/ou ao BWTP. O suporte ao Google Wave e protocolos afins também estão nas nossas prioridades.
InfoQ: Existem outros planos para o Jetty/Google?
O Google mantém os seus planos dentro do seu baú, logo não sabemos o que acontecerá. Nós conversamos com os desenvolvedores da App Engine no JavaOne e abrimos para eles um espaço para qualquer feedback, afim de melhorar a extensabilidade e capacidade em trabalhar de forma embutida do Jetty.
Em uma reunião de revisão com o time da Webtide, o InfoQ também questionou sobre a decisão da SpringSource em utilizar o Tomcat ao invés do Jetty.
InfoQ: Vocês sabem porque a SpringSource está mudando o Grails para utilizar Tomcat como seu container padrão ao invés do Jetty?
A justificativa foi que os líderes de desenvolvimento do Grails perceberam que poderão ter um melhor atendimento para os defeitos lidando com os desenvolvedores internos do Tomcat. Imagino que isso tem como objetivo direcionar os usuários do Grails a uma plataforma que a SpringSource poderá vender serviço de suporte. Vimos algo similar com o JBoss, que substituiu o Jetty pelo Tomcat há muitos anos atrás, quando eles contrataram desenvolvedores do tomcat e acabaram cancelando o acordo comercial com a Mort Bay. É um pesar que acordos comerciais como esse influenciem as decisões técnicas, mas nós estamos em uma fase onde a infraestrutura dos projetos estão agregando aos servidores de aplicações.
O Grails irá continuar tendo integração ao Jetty quanto ao Tomcat, mas colocaremos o Tomcat como o padrão.
Parece ser uma importante decisão, especialmente com o uso/relacionamento do Tomcat pela SpringSource.