• Nenhum resultado encontrado

Java. no Google App Engine. Escreva aplicações Java para o serviço de Cloud Computing da Google

N/A
N/A
Protected

Academic year: 2021

Share "Java. no Google App Engine. Escreva aplicações Java para o serviço de Cloud Computing da Google"

Copied!
5
0
0

Texto

(1): : www.mundoj.com.br : :. Pedro Mariano (pedro.mariano@caelum.com.br): é técnologo em Análise e Desenvolvimento de Software pela FIAP, possui a certificação SCJP 6. Trabalha como consultor e desenvolvedor pela Caelum com linguagens como Ruby e Java.. Pedro Matiello (pedro.matiello@caelum.com.br): trabalha como consultor e desenvolvedor pela Caelum e é aluno do curso de Bacharelado em Ciência da Computação no IME-USP.. Java no Google App Engine Escreva aplicações Java para o serviço de Cloud Computing da Google Atualmente, o Cloud Computing é um dos assuntos mais comentados na área de TI. Assunto este que já é realidade no mercado: diversas empresas, como Amazon, RackSpace e Microsoft, já possuem soluções de infraestrutura em cloud. A Google também entrou neste mercado e já oferece um ambiente de Cloud Computing no qual os desenvolvedores podem colocar suas aplicações: o Google App Engine. Este artigo aborda exemplos práticos de uma aplicação Java com VRaptor 3 construída para o AppEngine.. Cloud Computing — normalmente traduzido para o português como Computação nas Nuvens — está em grande ascendência. Esse crescimento é impulsionado pela necessidade de se ter sistemas escaláveis, com alta disponibilidade e altamente performáticos. Mas um fator que tem sido frequentemente destacado como motivação para adoção de soluções de cloud é a forte redução no custo de manutenção da parte de infraestrutura das aplicações. Como as tarefas de infraestrutura são realizadas pelo provedor do serviço, a equipe de desenvolvimento pode se focar apenas em criar a aplicação que, idealmente, irá escalar automaticamente, seguindo a demanda. Na maioria das vezes, a tarifação destes serviços é feita de forma a cobrar pela quantidade de recursos consumidos, tais como espaço de armazenamento e tempo de processamento. 0PCKFUJWPEFTUFBSUJHPÏBQSFTFOUBSP73BQUPSFNDPOKVOUPDPN o Google AppEngine, com exemplos de uso dos recursos providos pelo serviço. 30.

(2) Google App Engine A Google também decidiu oferecer um serviço de Cloud Computing, denominado Google App Engine (GAE). Mesmo estando em fase beta, diversas empresas, como a BestBuy com o seu produto GiftTag, estão utilizando o GAE. Diferentemente de muitos de seus concorrentes, a Google oferece um plano inicial gratuito, que é suficiente para aplicações e sites de pequeno e talvez até de médio porte (permite-se, por exemplo, até 1.300.000 requisições gratuitas ao banco, por dia). Aplicações consumindo recursos além dos estipulados neste plano são tarifadas de forma proporcional ao que foi consumido além dos limites da cota gratuita. Atualmente, o GAE suporta duas linguagens de programação: Java e Python, e ambas com algumas restrições quanto ao que se pode fazer no ambiente. Em grande parte dos casos, o próprio GAE oferece uma alternativa através de uma API proprietária, que é bastante concisa e fácil de trabalhar, mas que prende a aplicação ao serviço (o chamado vendor lock-in).. App Engine além do Python e Java Apesar de o GAE oficialmente oferecer suporte apenas para Java e Python, é possível também criar aplicações Ruby, Scala e JavaScript. Com Ruby, é necessário que você utilize o JRuby e com JavaScript o Rhyno. De uma forma geral, o GAE oferece TVQPSUFBRVBMRVFSMJOHVBHFNRVFQPTTBTFSFYFDVUBEBOB+7. Devido à grande popularidade do framework Rails, correm rumores de que a Google estaria interessada em oferecer suporte nativo para a linguagem Ruby.. Esta API exclusiva do App Engine oferece acesso aos serviços do GAE disponíveis para realizar tarefas comuns e nem tão comuns, tais como envio de e-mails, persistência de dados, execução assíncrona (tasks) e agendada (cron). Neste artigo são abordados alguns desses serviços, dando detalhes de seu uso e algumas dicas.. prometê-lo, e só fazer a troca quando estiver tudo como esperamos. Trata-se de uma estratégia de deploy contínuo [2] como a apresentada por Martin Fowler [3].. GAE e o VRaptor 3 Por causa da grande quantidade de componentes restritos, muitos fraNFXPSLT.7$ JNQMFNFOUBÎÜFTEF+4' NBQFBEPSFT9.-FUD FYJHFN BKVTUFTQBSBSPEBSOP"QQ&OHJOF FPNFTNPBDPOUFDFDPNP73BQUPS Ele oferece um download específico pronto para todos os desenvolvedores interessados em utilizar o framework no cloud da Google. Este é VNQSPKFUPFNCSBODPQBSBP&DMJQTF KÈDPNP73BQUPSBEBQUBEP FÏ feito para ser usado como ponto de partida de novos projetos. Para começar, instale o plugin do App Engine [4] no Eclipse, baixe e importe o projeto vraptor-blank-project-gae, ajuste o classpath de acordo com a versão do SDK do GAE (que acompanha o plugin) e o nome da aplicação no appengine-web.xml. Feito isso, podemos começar a FTDSFWFSBQMJDBÎÜFTQBSBP"QQ&OHJOFVTBOEPP73BQUPS7PDFQPEF fazer deploy a qualquer momento clicando com o botão direito sobre o projeto no Eclipse e escolhendo Deploy to App Engine dentro do submenu Google. 7FKBOBT-JTUBHFOTFVNFYFNQMPEFDPOUSPMMFSEP7SBQUPSRVF possui um método que disponibiliza a mensagem "olá mundo" para a view.. Para Saber Mais Na edição 38 da Revista MundoJ você pode conferir um tutoSJBMDPNQMFUPEP73BQUPS. -JTUBHFN6NDPOUSPMMFSDPN73BQUPS @Resource public class IndexController { @Path(“/”) public String index() { return “ola mundo”; }. Nossa experiência com o GAE Em 2009, completamos a migração do nosso site [1] para o App &OHJOF/PTTBBQMJDBÎÍPGB[VTPEPGSBNFXPSL.7$73BQUPS  que oferece uma configuração específica para rodar no GAE, feita para contornar as restrições do ambiente de execução do serviço. Após todos estes meses, podemos dizer que a experiência é bastante satisfatória. Dentre as vantagens do serviço, destacamos sua escalabilidade, que nos permitiu aguentar picos de acesso ao site da Caelum sem comprometer o desempenho e a disponibilidade do site. A interface administrativa do App Engine também se mostrou muito conveniente, permitindo analisar os logs e relatórios de desempenho do site de forma bastante simples. Outro recurso muito útil do GAE é o sistema de versionamento das aplicações: é possível ter versões diferentes de sua aplicação instaladas e rodando concorrentemente. Desta forma, podemos testar novas versões do site no ambiente de produção sem com-. }. -JTUBHFN7JFXQBSBP$POUSPMMFSEB-JTUBHFN ... <body> ${string} </body> .... Persistência O App Engine oferece como mecanismo de persistência um banco de dados (Datastore) orientado a documentos que tem como base o BigTable. Trata-se de um banco proprietário e desenvolvido pela própria. 31.

(3) : : www.mundoj.com.br : :. Google, com foco em alto desempenho e escalabilidade. O Google App Engine oferece três formas diferentes de acessar o Datastore: uma API de baixo nível (não muito utilizada por ser complexa), o JDO (Java Data Objects) e a JPA (Java Persistence API). Estas duas últimas são APIs mais simples e familiares aos desenvolvedores Java, mas também não foram projetadas para o Datastore e suas características incomuns, mas sim para modelos mais tradicionais de persistência. Além disso, as entidades, sempre que criadas ou modificadas, precisam passar por um processo de pós-compilação um tanto inconveniente. Para contornar as dificuldades de usar o JDO ou a JPA no GAE, novos projetos open source surgiram com APIs alternativas de persistência levando em conta peculiaridades do Datastore. Dentre elas, destacamse o Twig, o SimpleDS e o Objectify. Nós optamos pelo Objectify por sua simplicidade e boa documentação. Esta API se define como uma camada fina sobre o Datastore, respeitando suas características estruturais, mas de uma forma mais usável pelos programadores.Para começar, definimos uma entidade. No Objectify, as entidades são POJOs acrescidos de um identificador que deve ser um Long ou uma String anotado com @Id. A Listagem 3 apresenta um exemplo simples de entidade. A Listagem 4 apresenta um DAO para esta classe, que a registra no Objectify e realiza operações de escrita e leitura. Listagem 3. Entidade Carro. class Carro { @Id private Long id; private String cor; private String placa; private boolean licenciado; // getters e setters ... }. Listagem 4. DAO para entidade Carro como componente EP73BQUPS @Component class CarroDAO { ObjectifyService datastore; static { ObjectifyService.register(Carro.class); } public CarroDAO() { datastore = ObjectifyService.begin(); } public void salva(Carro carro) { datastore.put(carro); } public Carro busca(Long id) { return datastore.get(Carro.class, id); } public void deleta(Carro carro) { datastore.delete(carro); } } 32. Além destas três operações (get, put, delete), uma quarta é suportada pelo Objectify: query. Através de uma interface fluente, pode-se realizar consultas ao datastore em busca de entidades que satisfaçam determinados critérios. A Listagem 5 apresenta um método que devolve todas as entidades do tipo Carro armazenadas no banco da aplicação. Listagem 5. Método para buscar todos os carros. @Component public List<Carro> buscaTodos() { return datastore.query(Carro.class).list(); }. A Listagem 6 apresenta um método que devolve todos os carros de uma determinada cor, e a Listagem 7 apresenta um método que busca um Carro através de sua placa. Listagem 6. Método para buscar todos os carros de uma cor. public List<Carro> buscaDaCor(String cor){ return datastore.query(Carro.class).filter(“cor”, cor).list(); }. Listagem 7. Método para buscar todos os carros de uma cor. public Carro buscaComPlaca(String placa){ return datastore.query(Carro.class).filter(“placa”, placa).get(); }. O Objectify ainda disponibiliza outros métodos para refinar as DPOTVMUBT  UBJT DPNP PSEFS  PGGTFU  F MJNJU  7FKB VNB RVFSZ mais complexa na Listagem 8, que utiliza métodos combinados para gerar uma consulta mais refinada. Listagem 8. Método que busca os dois últimos carros cadastrados de determinada cor.. public List<Carro> ultimosDoisCarrosCadastradosDaCor(String cor){ //o método order por padrão é crescente caso você queira que seja // decrescente utilize //o carácter - na frente do atributo datastore.query(Carro.class) .filter(“cor”, cor) .order(“-id”) .limit(2) .list(); }. O Objectify também possibilita que você crie relacionamentos dos tipos One-to-Many e Many-to-One. Na Listagem 9 pode-se ver um exemplo no qual mapeamos a classe Carro com a classe Motorista, dizendo que um Carro possui um motorista..

(4) Listagem 9. Entidade Carro com o atributo Motorista com o relacionamento Many-to-One. class Carro { @Id private Long id; private String cor; private String placa; private String licenciado; Key<Motorista> motorista; // getters e setters ... }. Perceba que o atributo motorista é do tipo Key. Isso é necessário, pois o objectify não faz relacionamentos “managed” como a JPA ou o JDO, portanto, ele armazena os dados do relacionamento nessa classe genérica chamada Key. 7FKB OB -JTUBHFN  VN FYFNQMP VUJMJ[BOEP P SFMBDJPOBNFOUP one-to-many em que um carro possui um ou mais motoristas. Perceba que a única diferença é que o atributo motoristas é um array de Keys. Listagem 10. Entidade Carro com o atributo Motoristas definindo um relacionamento One-To-Many. class Carro { @Id private Long id; private String cor; private String placa; private String licenciado; Key<Motorista>[] motoristas; // getters e setters ... }. Quando estiver utilizando o Datastore tenha em mente que, por ele não ser um banco de dados relacional, possui algumas limitações. Relacionamentos many-to-many, consultas polimórficas e com agregações (sum, avg, max etc.) não são suportadas. Estas características são comuns em bancos não-relacionais, como o BigTable, que trocam parte das funcionalidades para obter maior desempenho e escalabilidade. Frameworks como o Twig oferecem uma forma mais natural de fazer relacionamentos sem a necessidade de se utilizar uma classe específica, que no caso do objectify é a Key. Porém, o Twig ainda possui alguns bugs e por isso não o escolhemos. Além disso, é bastante comum, e até indicado, que se tenham resultados do BigTable. Para isso, podemos usar o serviço de memcache do GAE. Além de aumentar a performance, é também uma questão de disponibilidade, já que o BigTable pode apresentar downtimes.. Tasks Outro recurso importante do GAE é a possibilidade de criar tarefas (Tasks) e inseri-las em uma fila (criada por você ou então o padrão que o Google oferece). Esta fila é gerenciada pelo próprio App Engine, que. irá detectar novas inserções e executá-las sempre que houver recursos disponíveis para tal. Trata-se de um mecanismo de execução assíncrona: embora uma carga de trabalho seja iniciada por uma requisição, sua execução ocorre fora desta requisição. A motivação natural para o uso deste mecanismo é a execução de tarefas que não exigem uma resposta imediata para o cliente ou que podem consumir excessivamente os recursos do sistema se realizadas de forma desordenada. Uma tarefa, aqui, é entendida como um método que realiza algum trabalho acrescido dos dados relevantes para sua execução. O método é endereçado por uma URL e os dados são passados como parâmetros de requisição. Quando uma tarefa é selecionada para a execução, o GAE realiza uma requisição HTTP para a URL especificada com os parâmetros dados. /B-JTUBHFNUFNPTVNBDMBTTFEFVNDPOUSPMBEPSQBESÍPEP7SBQtor 3 com um método para verificar o licenciamento de uma placa. Esse método será chamado de forma assíncrona pela tasks API, como demonstrado no exemplo da Listagem 12. No nosso cenário vamos asTVNJSRVFUFNPTVNBDMBTTF7FSJmDBEPS%F1MBDBRVFBDFTTBVNTJTUFNB do governo que, ocasionalmente, pode não estar acessível. Caso o sistema esteja inacessível, a Tasks API irá tentar de novo até que o processo seja feito com sucesso. Esse exemplo ilustra uma das vantagens de se utilizar a API de Tasks, garantindo que seu processo será executado. -JTUBHFN$POUSPMMFSQBESÍPEP73BQUPSDVKBGVOção é verificar se a placa passada está licenciada. @Resource public class CarroController { @Path(value=”/verificaPlaca/”) public void verificaPlaca(String placa) { boolean estaLicenciado = new VerificadorDePlaca().verificaPlaca(placa); //atualiza localmente o status do carro. Carro carro = carroDAO.buscaComPlaca(placa); carro.setLicenciado(estaLicenciado); carroDAO.salva(carro) } }. Listagem 12. Colocando na fila de tarefas a execução da verificação de determinada placa. Queue queue = QueueFactory.getDefaultQueue(); queue.add(url(“/verificaPlaca”).param(“placa”,”ABC7887”));. A criação de tarefas corresponde, na prática, à inserção de URIs numa fila. A execução de uma tarefa, portanto, corresponde a realizar uma requisição para a URI associada. Esta requisição, por sua vez, deve ter como resposta um código de retorno HTTP — 200 (OK) em caso de sucesso, e qualquer outro valor em caso de falha. Caso a resposta indique a ocorrência de um erro no processamento, a tarefa será reinserida na fila para ser processada novamente. É possível também limitar o número de tentativas através da criação de outra fila e da adição do header HTTP X-AppEngineTaskRetryCount com o número máximo de tentativas. 33.

(5) : : www.mundoj.com.br : :. 0VUSPTTFSWJÎPT Além da execução assíncrona e da persistência, o App Engine oferece outros serviços que podem ser úteis ou mesmo essenciais para algumas aplicações web. t .FNDBDIFDBDIFEJTUSJCVÓEPEFPCKFUPTFNNFNØSJB/PSNBMmente, usado para acelerar o acesso a objetos do Datastore. t 63-'FUDISFRVJTJÎÜFT)551F)5514QBSBDPNVOJDBÎÍPDPN outros hosts na web. t .BJMFOWJPFSFDFCJNFOUPEFFNBJMT t 9.11FOWJPFSFDFCJNFOUPEFNFOTBHFOTJOTUBOUÉOFBT t *NBHFTNBOJQVMBÎÍPEFJNBHFOT SPUBÎÍP SFDPSUF SFEJNFOTJPnamento etc.). t 6TFSTBVUFOUJDBÎÍPWJB(PPHMF"DDPVOUT t 0"VUIBVUFOUJDBÎÍPWJBQSPUPDPMP0"VUI t 5BTLTQSPDFTTBNFOUPBTTÓODSPOP t #MPCTUPSFBSNB[FOBNFOUPEFPCKFUPTHSBOEFT Ao utilizar qualquer serviço do GAE, informe-se a respeito do limite para uso gratuito do mesmo e das taxas aplicáveis para uso além deste limite. Além disso, alguns serviços estão em fase beta e o Google não garante total disponibilidade e/ou estabilidade do mesmo.. Limitações e cuidados Para garantir a segurança e a escalabilidade do serviço, o App Engine impõe algumas restrições sobre as aplicações nele hospedadas. Para começar, dentre as classes do JRE, apenas um subconjunto é suportado [6]. Também não é permitida a criação de threads, arquivos ou sockets, mas estas restrições podem ser, em muitos casos, contornadas pela API de Tasks, pelo Datastore, e pelas APIs de Email e HTTP específicas do GAE. As views e JSP exigem um cuidado a mais: o suporte a Expression Language vem desativado por padrão e não pode ser habilitado globalmente. Neste caso, é preciso adicionar a linha abaixo em todo arquivo JSP que faz uso de EL:. ferramentas e serviços que facilitam a vida do desenvolvedor e aumentam a produtividade da equipe. As limitações, contudo, são uma realidade, e adaptações tanto no modo de programar quanto na forma de estruturar sua aplicação deverão ser consideradas ao se desenvolver aplicações para o GAE. A situação em vista é, claramente, uma troca: disponibilidade, confiabilidade e segurança são obtidas a custo de alguma flexibilidade. Outras plataformas, como serviço (PaaS), estão aparecendo para a plataforma Java, e algumas com menos restrições: FTTBÏBQSPNFTTBEB7.8BSFFEB4QSJOH4PVSDFBUSBWÏTEB7. Force [7], que estará disponível em alguns meses. A Caelum, como anteriormente mencionado, utiliza o GAE em seu site. A experiência tem se mostrado cada vez mais compensadora e satisfatória. A curva inicial de aprendizado e de adaptação pode ser transposta sem maiores problemas e o investimento inicial é pago rapidamente com menores custos de administração do servidor e pela proteção contra picos de acesso. A Google melhora o App Engine constantemente e, mensalmente, novas versões do kit de desenvolvimento são lançadas. Se você é um programador interessado em criar aplicações escaláveis gastando pouco ou nada com infraestrutura, realmente vale a pena EBSVNBPMIBEBOP("&t. App Engine for Business Recentemente, a Google anunciou uma nova versão do GAE com o foco em aplicações “enterprise”. De acordo com a Google, a intenção é continuar oferecendo serviços do nível do Google App Engine, acrescido de suporte e de alguns serviços como o suporte a incluindo um banco de dados relacional e SSL. O App Engine for Business [8] é oferecido a um preço de 8 dólares por usuário além das taxas de consumo.. <%@ page isELIgnored="false" %> Por fim, outro detalhe que merece bastante atenção é o tempo de inicialização das instâncias (conhecido como cold start). Quando sua aplicação é chamada pela primeira vez, uma instância é criada e executada por um dos servidores da nuvem. Este processo é lento, podendo consumir vários segundos, dependendo tanto da disponibilidade de recursos no GAE naquele momento como do tamanho da aplicação e das bibliotecas e frameworks usados. Os acessos seguintes são respondidos com baixa latência, mas, após um período de inatividade, as instâncias são destruídas, exigindo que todo o lento processo de inicialização seja refeito pelo serviço em um próximo acesso. Para evitar isso, a prática mais comum tem sido usar o agendador de tarefas do próprio App Engine para visitar alguma página do site a cada minuto, mantendo assim uma instância da aplicação sempre ativa. A Google diz estar estudando outra forma de contornar o problema.. Considerações finais A solução de Cloud Computing da Google certamente tem atraído grande atenção. Por um baixo custo, é possível obter, com este serviço, um alto nível de segurança e escalabilidade, além de 34. Referências <>IUUQCMPHDBFMVNDPNCSFTDSFWFOEPFNJHSBOEPBQMJDBDPFTQBSB PHPPHMFBQQFOHJOF <>IUUQCMPHDBFMVNDPNCSPQSPDFTTPEFEFQMPZDPOUJOVP <>IUUQNBSUJOGPXMFSDPNCMJLJ#MVF(SFFO%FQMPZNFOUIUNM <>IUUQDPEFHPPHMFDPNBQQFOHJOFEPDTKBWBUPPMTFDMJQTFIUNM <>IUUQDPEFHPPHMFDPNQWSBQUPSEPXOMPBETMJTU <>IUUQDPEFHPPHMFDPNBQQFOHJOFEPDTKBWBKSFXIJUFMJTUIUNM <>IUUQCMPHTQSJOHTPVSDFDPNWNGPSDFTQSJOHDMPVE <>IUUQDPEFHPPHMFDPNBQQFOHJOFCVTJOFTT.

(6)

Referências

Documentos relacionados

Constitui o objeto do presente CONTRATO, a prestação pela CONTRATADA de exames laboratoriais e complementares aos beneficiários da CONTRATANTE, nas condições

Durante o uso concomitante de outros medicamentos que contenham etinilestradiol e substâncias que podem diminuir as concentrações séricas de etinilestradiol, recomenda-se que

A assistência da equipe de enfermagem para a pessoa portadora de Diabetes Mellitus deve ser desenvolvida para um processo de educação em saúde que contribua para que a

Para incêndios de grandes proporções, utilizar spray de água ou espuma.. Água pode

Aristóteles considera a capacidade de julgamento (avaliação) dos homens, que lhes decorre tanto de seu conhecimento, quanto de sua experiência - “um jovem,

Caso este equipamento apresente alguma não conformidade, encaminhe-o para a Assistência Técnica Autorizada VONDER

No sentido de reverter tal situação, a realização deste trabalho elaborado na disciplina de Prática enquanto Componente Curricular V (PeCC V), buscou proporcionar as

• Não há inflação de alimentos, há inflação, causada por choques cambiais, auxílio emergencial, problemas fiscais e má gestão de estoques públicos;. • O Brasil precisa