• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine
 

Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine

on

  • 3,690 views

Palestra dada em 11/SET/2010 no QConSP

Palestra dada em 11/SET/2010 no QConSP

Statistics

Views

Total Views
3,690
Views on SlideShare
3,645
Embed Views
45

Actions

Likes
8
Downloads
0
Comments
0

4 Embeds 45

http://www.techgig.com 35
https://twimg0-a.akamaihd.net 6
http://115.112.206.131 3
http://www.slideshare.net 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine Document Transcript

    • Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine @sergio_caelum | Caelum | QCon São Paulo 2010
    • Sérgio Lopes sergio.lopes @caelum.com.br @sergio_caelum Meu nome é Sérgio Lopes, sou instrutor e desenvolvedor na Caelum. Meu e-mail é sergio.lopes@caelum.com.br e meu twitter é @sergio_caelum. Sou um feliz desenvolvedor do Google AppEngine há 1 ano, quando resolvemos migrar o Caelum.com.br para o AppEngine em Setembro de 2009. Essa palestra é sobre o que aprendemos nesse 1 ano no cloud do Google. @sergio_caelum | Caelum | QCon São Paulo 2010
    • O que aconteceria ao seu sistema se os acessos dobrassem agora? Independente do tamanho do sistema hoje, imagine que ele aguente X usuário. Se neste exato instante chegassem 2X, o que aconteceria? E 3X? 5X? @sergio_caelum | Caelum | QCon São Paulo 2010
    • 14 dias de tráfego e Esse é o gráfico de Requests/segundo do site da Caelum ao longo de duas semanas normais em Agosto/Setembro de 2010. Até que um belo dia acontece o lançamento da nova apostila de Rails 3 do curso RR-71 da Caelum... @sergio_caelum | Caelum | QCon São Paulo 2010
    • 14 dias de tráfego e BUM! ... e, em apenas um instante, os acessos ao Site quintuplicam! Enviamos uma campanha em newsletter para milhares de inscritos, divulgamos no Blog com milhares de leitores e várias pessoas twitam. Tudo simultaneamente, em uma fria manhã de quinta- feira. Como lidar com esse tipo de pico? Como gerenciar os recursos computacionais necessários para segurar o tranco? E mais, sem desperdiçar recursos nem antes e nem depois; afinal o normal do site não é esse volume de acessos e o pico logo acaba. Podemos lançar por partes. Enviar a newsletter aos poucos para pequenos grupos. Divulgar no Blog apenas no dia seguinte. Mas piorar a experiência dos usuários por limitações técnicas? Perder aquele momento de marketing onde milhares e milhares de pessoas estão falando de você? Você passa a vida toda desenvolvendo um produto e querendo que ele dê certo. E um belo dia ele estoura em sucesso. Como seu sistema reage? Ele capota ou segura o tranco naquele momento importantíssimo de crescimento? No fim de 2009, sem sabermos, o portal da revista InfoExame fez uma matéria citando nossas apostilas abertas. Foi uma correria para downloads, muitos e muitos acessos no site. Imagine não aguentar o tranco em um momento tão especial e com tanta visibilidade como esse? @sergio_caelum | Caelum | QCon São Paulo 2010
    • Cloud Computing A solução rápida e fácil? Cloud computing e computação elástica @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade infinita Com uma aplicação em cloud, conseguimos aguentar volumes altíssimos de tráfego sem preocupação @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade infinita Elasticidade Mas o principal é conseguir atender a essa demanda de escalabilidade nos momentos em que ela for necessária. O cloud é elástico porque consegue alocar mais recursos no momento que for necessário e liberar esses recursos quando não for mais necessário. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade infinita Elasticidade Disponibilidade Sem o trabalho de manutenção de infra, gerenciamento de backups, replicação, clusters etc, sua aplicação acaba mais disponível no cloud @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade infinita Elasticidade Disponibilidade Mais barato Por causa da elasticidade do cloud, os recursos usados são apenas os estritamente necessários no momento, sem desperdício, sem recursos ociosos. Logo, com um melhor aproveitamento dos recursos computacionais, geramos economia de custo. Fora a terceirização do trabalho que traz economias de recursos pela escala. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Infraestrutura como serviço IaaS Quando falamos de cloud, a primeira coisa que vem à cabeça é oferecer uma infraestrutura de hardware pronta onde podemos comprar recursos de hardware infinitamente. Processamento, armazenamento, banda, etc. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Infraestrutura como serviço IaaS PaaS Plataforma como serviço Mas muito tem se falado também em oferecer uma Plataforma de desenvolvimento em cima dessa infraestrutura, para não ser apenas um monte de hardware. O Google AppEngine é um PaaS. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Infraestrutura como serviço IaaS PaaS Plataforma como serviço Palestra “Arquiteturas em Cloud” Com Fábio Kung, amanhã às 16h10 (para entender melhor esses termos e conceitos, não percam a palestra do Kung) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Infraestrutura e qualidade Google Sobre o Google AppEngine especificamente. Temos primeiro o oferecimento da infraestrutura e qualidade de serviços Google, capaz de escalar absurdamente. É a mesma infra e tecnologia usada nos serviços deles. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Ambientes Java e Python São disponibilizados dois ambientes de execução, um Python e um Java. Por oferecer Java, podemos rodar ainda JRuby, Scala etc @sergio_caelum | Caelum | QCon São Paulo 2010
    • Persistência com BigTable Além da plataforma de execução, é oferecido um serviço de persistência (Datastore) usando o famoso BigTable do Google. É um banco NoSQL, orientado a coluna, consistente e particionável (CP do CAP). @sergio_caelum | Caelum | QCon São Paulo 2010
    • Persistência com BigTable Palestra “NoSQL Erros e Acertos” Com Gleicon Moraes e Alexandre Porcelli Amanhã às 18h10 (para entender melhor NoSQL, não percam a palestra amanhã) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Pague pelo que usa E um recurso bem interessante é o pagamento pelo uso dos recursos, com controle de quotas e valores bem acessíveis @sergio_caelum | Caelum | QCon São Paulo 2010
    • Pague pelo que usa Paga-se pelo uso de CPU, pela banda, pelos dados armazenados e o número de e-mails enviados. Repare que existe uma quota free que é suficiente para muitos e muitos casos. E mesmo quando você começar a pagar, é muito barato. Um centésimo de centavo por e-mail enviado; Meio centavo por GB armazenado Introduzido o AppEngine, queria falar alguns pontos legais e algumas dicas sobre o que aprendemos nesse último ano @sergio_caelum | Caelum | QCon São Paulo 2010
    • #1 Ambiente de Dev Primeiro ponto: Ambiente de Dev @sergio_caelum | Caelum | QCon São Paulo 2010
    • Eclipse + AppEngine SDK + Plugin Um dos pontos fortes é você usar um ambiente conhecido. Eclipse com Java e um excelente plugin que integra todas as APIs do SDK. Tudo de graça e facilmente instalável. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Eclipse + AppEngine SDK + Plugin One-click deploy E é ridiculamente fácil fazer o deploy da aplicação: só clicar no botão. Não precisa gerenciar instâncias, alocar recursos, nada. Só apertar o botão e sua aplicação está lá, escalando infinitamente e elasticamente. @sergio_caelum | Caelum | QCon São Paulo 2010
    • #2 Fácil Gerenciamento Segundo ponto: recursos para gerenciamento remoto da aplicação de modo simples @sergio_caelum | Caelum | QCon São Paulo 2010
    • Painel de Controle Há um completo Painel de Controle em http://appengine.google.com @sergio_caelum | Caelum | QCon São Paulo 2010
    • Painel de Controle Dashboard - Gráficos e informações completas sobre o uso de quota e comportamento da aplicação. Páginas mais acessadas, incidência de erros etc @sergio_caelum | Caelum | QCon São Paulo 2010
    • Painel de Controle Logs completos de requests, erros e mensagens da aplicação. Você ainda pode baixá-los offline no formato Apache e processar com qualquer log analyzer como Analog. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Painel de Controle Data Viewer - Observar os dados, editá-los, executar queries no DataStore. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Versões Um recurso bem bacana do GAE é a execução de versões diferentes da aplicação simultaneamente @sergio_caelum | Caelum | QCon São Paulo 2010
    • Versões No momento do deploy, edita-se um XML do GAE indicando a versão. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Versões Depois é possível acessar as versões pelo Painel de Controle. Bons usos é ter uma versão de produção e uma de testes (PS. cuidado que o DataStore é compartilhado!). Outro uso são versões com funções especiais, como importar ou exportar dados, ou processar alguma coisa pontualmente. Fazer o switch entre versões é trivial: basta marcar como Default e pronto. No exemplo acima, temos um servidor de integração contínua colocando no ar automaticamente a versão de testes a cada push pro repositório GIT. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Status E, importante para confiar no serviço remoto oferecido, é transparência no momento de possíveis falhas @sergio_caelum | Caelum | QCon São Paulo 2010
    • Status Transparência e visibilidade com relação ao status do sistema e dos subsistemas do AppEngine, com histórico e relatórios detalhados de cada problema ou anomalia. @sergio_caelum | Caelum | QCon São Paulo 2010
    • #3 Padronização Uma das maiores preocupações ao se envolver em uma PaaS é com relação a portabilidade. Desenvolvo pensando no AppEngine. Mas e se quiser mudar? O pessoal do Google pensou nisso e pretende apoiar o maior número de especificações Java quanto for possível, gerando baixo acoplamento com os serviços proprietários deles. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Servlets 2.5 e JSP 2 Especificações Java Web padrão com algumas pequenas restrições (por exemplo, ausência de contextDestroyed). Isso permite rodar qualquer framework construído em cima do padrão, como Struts, JSF, GWT, VRaptor, Spring MVC etc @sergio_caelum | Caelum | QCon São Paulo 2010
    • Servlets 2.5 e JSP 2 JPA 1 e JDO 2 Implementação das especificações JPA 1 e JDO 2 via um fork do projeto DataNucleus. A ideia é abstrair o Datastore não relacional do GAE através de uma API portável e conhecida. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Servlets 2.5 e JSP 2 JPA 1 e JDO 2 java.net Integração remota com java.net.URL para acesso HTTP e HTTPS. Usa o serviço URLFetch do GAE por baixo. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Servlets 2.5 e JSP 2 JPA 1 e JDO 2 java.net JavaMail Envio e recebimento de e-mails pela especificação JavaMail da Sun (pacote javax.mail). Mas sem precisar se preocupar com SMTP, POP, configurações etc @sergio_caelum | Caelum | QCon São Paulo 2010
    • Servlets 2.5 e JSP 2 JPA 1 e JDO 2 java.net JavaMail JCache [ JSR107 ] Acesso a memcache distribuído através do JCache @sergio_caelum | Caelum | QCon São Paulo 2010
    • #4 BigTable não é relacional O quanto antes você perceber isso, melhor será pra você. Implicações: “Usar JPA para acessar o BigTable é complicado” “Suas aplicações não serão tão portáveis assim” @sergio_caelum | Caelum | QCon São Paulo 2010
    • Sem funções de agregação! count, sum, avg, max, min, group by, having, ... As entidades salvas são meros punhados de dados, não há schema definido, não há restrições. As agregações ficam por conta do programador. Por exemplo, vamos implementar count(*) [parecido pra sum, avg, max, min]. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Sem funções de agregação! count, sum, avg, max, min, group by, having, ... Produto id nome preco 1 Chocolate 4.9 2 Macarrão 3.5 ... Imagine uma simples entidade Produto e uma tabela correspondente. Como saber quantos produtos existem? Como saber a média de precos? Precisamos de uma entidade auxiliar pra guardar nossas agregações... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Sem funções de agregação! count, sum, avg, max, min, group by, having, ... Produto AgregacoesProduto id nome preco id tipo coluna valor 1 Chocolate 4.9 1 count id 2 2 Macarrão 3.5 2 sum preco 8.4 ... 3 avg preco 4.2 E a cada update/insert/delete de Produto, precisamos atualizar as Agregacoes correspondentes. Pior é quando a tabela principal é muito atualizada. Haverá uma sobrecarga por exemplo na Agregacao de counts e as operações de escrita começarão a dar timeout e você perderá as informações. A solução é criar ShardedCounters, vários contadores diferentes, cada um contando uma parte das entidades. Para obter o count geral você precisa pegar todos os shards e somá-los. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Transações não são como estamos acostumados Como o GAE tem um storage distribuído, as entidades salvas estão espalhadas pelos nós físicos do Datastore. O GAE não permite então transações envolvendo várias máquinas diferentes. Conseguimos usar transações se todas as entidades manipuladas nela estiverem no mesmo Entity Group, o que garante a mesma localização física. Na hora de criar uma nova entidade, você pode dizer quem é Parent dela e ambas estarão no mesmo grupo. Porque então não colocamos tudo no mesmo Entity Group? Isso mataria escalabilidade, uma vez que o Google limita a quantidade de requests que podem ser feitos a um Entity Group. E acertar a modelagem dos Entities Groups é difícil porque se depois precisar envolver 2 groups diferentes, não conseguiremos. Outra característica: se houver contenção (transações manipulando mesmo dado paralelamente), sua transação falha. O dev deve tentar executá-la novamente, normalmente com um for. Na prática, muitas das garantias transacionais que estamos acostumados em DBs tradicionais são agora implementadas pelo programador. Links: http://code.google.com/appengine/docs/java/datastore/transactions.html http://code.google.com/p/objectify-appengine/wiki/Concepts#Transactions http://code.google.com/appengine/articles/transaction_isolation.html @sergio_caelum | Caelum | QCon São Paulo 2010
    • Transações não são como estamos acostumados Nada de Join Não é possível fazer Joins em buscas com relacionamentos, uma vez que envolveriam várias chamadas ao Datastore possivelmente envolvendo máquinas diferentes. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Transações não são como estamos acostumados Nada de Join Código específico - Uso da classe Key diretamente quando trabalhar com alguns relacionamentos - Muitas anotações de “extensão” para recursos específicos, como configurar o Parent - Variações na JPQL/JDOQL com coisas específicas do GAE, como batch reads No fim, há muitas diferenças entre um código JPA de verdade e um código JPA rodando no GAE. Perde-se então toda a teórica vantagem da portabilidade e chega-se a seguinte pergunta: já que vou perder portabilidade, porque usar JPA/JDO? Porque não usar ferramentas com menos abstrações e mais próximas do Datastore facilitando a integração com o GAE? Links: - Próprio pessoal do DataNucleus falando que a implementação do GAE é nojenta: http://datanucleus.blogspot.com/2010/01/gaej-and-jdojpa.html @sergio_caelum | Caelum | QCon São Paulo 2010
    • Datastore Low-level API Muita gente usa então alternativas para persistência. Primeiro a Low-level API oficial do GAE que permite acesso baixo nível a coisas do DataStore @sergio_caelum | Caelum | QCon São Paulo 2010
    • Exemplo de código da Low-level API, mostrando uso direto de Key e Entity. Repare que não há objetos e que podemos ter quantas propriedades quisermos em cada Entity. Inclusive Entitities (“linhas”) do mesmo Kind (“tabela”) podem ter propriedades (“colunas”) diferentes. Link: http://ikaisays.com/2010/06/03/introduction-to-working-with-app-engine%E2%80%99s-low- level-datastore-api/ @sergio_caelum | Caelum | QCon São Paulo 2010
    • Agora adicionamos a Entity @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui, temos uma busca de uma Entity a partir da chave dela (Key) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Objectify Como trabalhar com a Low-level API é trabalhoso, existem frameworks alternativos construídos em cima da Low-level API. Uma alternativa famosa é o Objectify, um framework escrito em cima da Low-level API, específico para o GAE, muito mais rápido e com facilidades importantes. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Modelamos nossa entidade usando um subset das anotações da JPA @sergio_caelum | Caelum | QCon São Paulo 2010
    • E aqui inserimos o objeto Noticia usando o Objectify @sergio_caelum | Caelum | QCon São Paulo 2010
    • Exemplo de código do Objectify. Parece JPA, mas é bem mais simples. Não retorna objetos managed por exemplo; não há dirty check etc
    • Twig Outro framework alternativo é o Twig @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui modelamos a entidade. Repare que nenhuma anotação é necessária. A chave também não fica na classe. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui inserimos usando o Twig, muito parecido com Objectify também. O store devolve a Key para depois fazermos uma busca, por exemplo. @sergio_caelum | Caelum | QCon São Paulo 2010
    • O Twig tem uma interface fluente para fazer buscas. Aqui estamos buscando todas as Noticias no Datastore. Poderíamos ainda adicionar wheres e orders por exemplo. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Mas um recurso bem legal e exclusivo do Twig (e da Low-level API) é a execução assíncrona de queries no GAE. A chamada ao returnResultsLater devolve um java.util.concurrent.Future e retorna imediatamente. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Isso me permite executar uma outra atividade no meio e depois voltar pra pegar o resultado da busca no meu Future @sergio_caelum | Caelum | QCon São Paulo 2010
    • #5 DataStore não é confiável e é lento O DataStore é um sistema distribuído gigantesco com características peculiares e está forte propenso a erros. Pelo teorema CAP, o BigTable é um CP: Consistente e Particionável. Mas não está sempre disponível para leituras e escritas. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Datastore read-only Uma primeira situação para a qual é bom estar preparado, é quando o Datastore está em manutenção e só oferece uma interface Read-only @sergio_caelum | Caelum | QCon São Paulo 2010
    • Ao tentar persistir alguma coisa (com JPA, Objectify etc)... @sergio_caelum | Caelum | QCon São Paulo 2010
    • ... o GAE lança uma Exception indicando a indisponibilidade do serviço. É bom estar preparado @sergio_caelum | Caelum | QCon São Paulo 2010
    • Use o Memcache O GAE oferece o memcache distribuído para sua aplicação. É bem mais rápido acessar coisas no cache que ir no Datastore. É uma boa usar o cache sempre que possível. http://code.google.com/appengine/docs/java/memcache/overview.html @sergio_caelum | Caelum | QCon São Paulo 2010
    • O código para obter a instância do Cache usando JCache @sergio_caelum | Caelum | QCon São Paulo 2010
    • Para o dev, toda a infra de cache parece um gigante HashMap. Apenas inserimos objetos associados a chaves e depois os buscamos. Bem simples de programar @sergio_caelum | Caelum | QCon São Paulo 2010
    • Um exemplo prático: uma busca no DAO. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Antes, vemos se não há notícia no cache. Se tiver, devolvemos ela. Se não tiver, buscamos no datastore e inserimos no cache, disponibilizando para futuras chamadas. Uma coisa importante é que o memcache não é um serviço de persistência. Não podemos contar com os dados inseridos lá, eles podem sumir a qualquer momento (por falha do sistema - que não é persistente - ou porque o GAE precisou de memória). Sua aplicação deve funcionar se o cache estiver faltando. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Cache de páginas Pouca gente sabe, mas existe um proxy reverso no GAE que faz cache de páginas transparentemente pra você. Basta configurar sua página para ser cacheável @sergio_caelum | Caelum | QCon São Paulo 2010
    • Coloque o header de Cache-control como public (nas páginas onde for possível isso) e configure o Expires. @sergio_caelum | Caelum | QCon São Paulo 2010
    • HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Expires: Sat, 11 Sep 2010 03:04:23 GMT Date: Sat, 11 Sep 2010 02:49:23 GMT Server: Google Frontend Cache-Control: public, max-age=900 Age: 532 O GAE tem um proxy reverso que faz cache de páginas e serve páginas cacheadas da sua aplicação transparentemente. Aqui vemos o conteúdo de um response cacheado. Repare no Server e no Age indicando há quanto tempo a página está no cache. No site da Caelum, economizamos várias horas de CPU cacheando páginas dessa maneira. @sergio_caelum | Caelum | QCon São Paulo 2010
    • #6 Cold Start Hell Um dos maiores problemas que as pessoas enfrentam no GAE é esse Cold Start. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Vamos entender como funciona o processo de inicialização e serviço de um container normal Java @sergio_caelum | Caelum | QCon São Paulo 2010
    • contextInitialized Deploy Startup do Contexto servlet.init() Primeiro, após o deploy da aplicação, ela é inicializada junto com o Contexto e alguns callbacks são chamados. (vários frameworks costumam inicializar aqui) @sergio_caelum | Caelum | QCon São Paulo 2010
    • contextInitialized Deploy Startup do Contexto servlet.init() Servindo requests servlet.service() Entra então a fase de servir os requests, quando o contexto já está quente e cada request executa uma chamada ao método service()... @sergio_caelum | Caelum | QCon São Paulo 2010
    • contextInitialized Deploy Startup do Contexto servlet.init() Servindo requests servlet.service() servlet.destroy() Shutdown contextDestroyed ... e, no fim, quando desligamos o contexto, os callbacks de destroy são chamados. Mas e no AppEngine? Não existe startup nem shutdown! Tudo é request! @sergio_caelum | Caelum | QCon São Paulo 2010
    • contextInitialized Startup do Contexto servlet.init() Servindo requests servlet.service() O startup é feito no primeiro request que chega na aplicação. Esse usuário tem que esperar o startup todo e depois a sua chamada ao service para receber a resposta. Os requests subsequentes executam só o service rapidamente. (e note que não há shutdown!) Mas o problema é a quantidade de vezes que o contexto é inicializado. Por ser escalável e elástico, o GAE está o tempo todo alocando e desalocando instâncias de contextos, mudando de máquinas, etc. Logo esse processo acontece diversas vezes por dia e vários usuários são então penalizados pelos requests em Cold Start. Se sua aplicação é pequena então, grandes chances que o GAE desaloque sua instância se você ficar sem acesso por poucos minutos. Solução?
    • Startup do Contexto contextInitialized servlet.init() Servindo requests servlet.service() O mais importante: diminuir o startup do contexto! Não use muitos frameworks e ainda aqueles que demandam alta inicialização. Cuidado com fw que fazem classpath scanning, cuidado com containers IoC que pré-inicializam um monte de coisas, cuidado com vários frameworks diferentes. A mudança do Datanucleus para o Objectfy, por exemplo, nos economizou vários preciosos segundos de startup! @sergio_caelum | Caelum | QCon São Paulo 2010
    • Startup do Contexto contextInitialized servlet.init() Servindo requests servlet.service() Ping Outra gambiarra para sistemas pequenos é pingar a aplicação de tanto em tanto tempo (2 min é uma boa) para manter uma instância quente. Isso diminui o número de cold starts mas não os evita completamente. Se você tiver um pico repentino, novas instâncias vão subir em paralelo; se o GAE precisar te mudar de máquina, uma nova instância sobe; etc. No site da Caelum, temos entre 20 e 30 Cold Starts por dia, mesmo usando as estratégias mencionadas. @sergio_caelum | Caelum | QCon São Paulo 2010
    • #7 Request hard limit O GAE é bastante limitado, como temos visto, para garantir escalabilidade e disponibilidade do serviço. Tudo no GAE é um request (inclusive o startup do contexto) e todo request tem um limite máximo de 30s para executar senão ele é morto. Além disso, não podemos iniciar novas Threads, tudo deve ser executado na thread no request. Como executar tarefas complexas então? Por exemplo acessar serviços remotos demorados? Ou executar grandes operações batch? Técnica importantíssima: fazer o máximo de coisas assincronamente... @sergio_caelum | Caelum | QCon São Paulo 2010
    • relembrando... Já vimos como o Twig permite acessar o DataStore assincronamente, liberando o request pra processar outras coisas enquanto a operação é efetuada no DataStore. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Outro momento que podemos ser assíncronos é na integração com outros sistemas. Chamamos uma URL que pode demorar para devolver um retorno, e podemos fazer isso de maneira assíncrona. Aqui usamos o serviço de URLFetch do Google que me devolve um Future, como no Twig PS. Você pode usar java.net.URLConnection mas ela não permite chamada assíncrona; só via a API low-level do URLFetcher do GAE @sergio_caelum | Caelum | QCon São Paulo 2010
    • Posso então processar outras coisas e voltar pra pegar a resposta depois. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Tasks A grande estrela são as Tasks. Você pode quebrar seu problema em pequenas partes (Tasks) e inseri-las para processamento assíncrono nas Task Queues do GAE. Mas o que são Tasks? Nada mais que requests automáticos disparados pra você em alguma URL específica. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Enviar uma task para processamento é bem simples. É uma URL HTTP que vai ser chamada pra você. Escreva sua Servlet ou o que for naquela URL e pronto! @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui um exemplo passando um parâmetro @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui um outro passando um corpo completo (payload) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Estudo de caso: envio de contatos no site da Caelum! O processo é bem simples: receber os dados, inserir no Banco e enviar e-mail. Mas precisamos também chamar um serviço remoto de matrícula que vai devolver um ID pra gente. A rotina síncrona é bem simples... @sergio_caelum | Caelum | QCon São Paulo 2010
    • ... recebemos o form, chamamos o servico pra pegar o ID, persistimos e depois enviamos o e-mail. Problemas: - E se a chamada remota der pau? - E se passar de 30s? - E se o datastore estiver fora? Solução: Tasks API! @sergio_caelum | Caelum | QCon São Paulo 2010
    • Vamos chamar o serviço remoto usando uma Task. Vantagens: - não bloqueia o usuário (isso pode demorar) - a task é executada até dar certo (cuidado pra preparar o serviço pra isso; e para implementar um algoritmo de desistência) Mas, e se o agendamento da Task falhar? Se o Datastore estiver fora? (Tasks dependem do datastore) @sergio_caelum | Caelum | QCon São Paulo 2010
    • O mais importante é enviar o e-mail, mesmo que sem a integração remota! Não podemos perder esse contato! Ok, mas agora, como tratar a chamada remota e a persistência? @sergio_caelum | Caelum | QCon São Paulo 2010
    • Meu controller que responde na URL da Task (aqui usando sintaxe do VRaptor) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Faço a chamada ao serviço remoto. Sem try/catch! Se falhar, o próprio GAE reagenda a Task para execução novamente! Mas isso pode ficar infinito, preciso de um ponto de parada... @sergio_caelum | Caelum | QCon São Paulo 2010
    • ... se estou tentando há mais de 30min, desisto da chamada remota e envio o e-mail logo. Preciso depois persistir e enviar o e-mail. Mas onde? Aqui mesmo? Não, assíncrono!
    • O e-mail é mais fácil porque o serviço é naturalmente assíncrono (o envio não é feito na hora, você nunca recebe um erro de resposta). PS. Repare aqui também que o e-mail é enviado em ambas as circunstâncias, com o serviço remoto funcionando ou não. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Crio uma nova Task de persistência. Assim ele fica tentando automaticamente se o primeiro insert falhar... e ainda quebra em coisas menores pra evitar o limite de 30s... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Aqui eu persisto o contato e fico tentando até dar certo. E não podemos esquecer da condição de parada caso a persistência falhe muitas vezes. PS. uma boa prática seria logar esses momentos que ele desiste de certa tarefa @sergio_caelum | Caelum | QCon São Paulo 2010
    • #8 Serviços legais Por último, uma das grandes vantagens do GAE, além da elasticidade do cloud, é a quantidade de serviços legais já prontos para uso. Já vimos vários, vamos ver mais alguns... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Recebimento de e-mails Tudo no AppEngine é um request! Inclusive receber emails! Caso legal: queremos mostrar as newsletters enviadas no Site da Caelum. Ao invés de fazer um cadastro de newsletters vamos inscrever o Site no sistema de envio de newsletter @sergio_caelum | Caelum | QCon São Paulo 2010
    • Recebimento de e-mails qualquercoisa@suapp.appspotmail.com recebimento@caelumcombr.appspotmail.com Toda aplicação ganha seu subdomínio no appspotmail.com e pode receber e-mails em diversos endereços. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Recebimento de e-mails Basta escrever uma Servlet respondendo na URL /_ah/mail/recebimento@caelumcombr.appspotmail.com .... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Recebimento de e-mails ... e tratar o request como uma mensagem do JavaMail, sem segredo @sergio_caelum | Caelum | QCon São Paulo 2010
    • Cron Serviço de agendamento de tarefas do GAE. Como sempre, é tudo request. Você indica a periodicidade e a URL de execução. Só. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Cron Temos uma URL aqui que importa posts do blog wordpress da Caelum, outro que importa o calendario.json do sistema de gerenciamento de turmas da Caelum e um terceiro que mantém a instância ativa, pingando a cada 2 min para minimizar a possibilidade de cold start. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Autenticação Google Há vários métodos de autenticação prontos, inclusive OpenID. Mas um dos mais simples e efetivos é usar contas do Google! Você ganha um sistema já pronto, confiável, seguro... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Autenticação Google No seu web.xml, basta usar uma <security-constraint> (padrão Java EE!!) para filtrar URLs. O role de admin só permite usuários cadastrados como admins da app a fazerem o login. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Autenticação Google Mas podemos permitir qualquer usuário Google também, mudando o role para * @sergio_caelum | Caelum | QCon São Paulo 2010
    • Autenticação Google E, em Java, podemos acessar o usuário logado, pegar seu e-mail ou seu ID da Conta do Google. @sergio_caelum | Caelum | QCon São Paulo 2010
    • BlobStore Esse é um dos serviços mais recentes disponibilizados pelo GAE. E um dos que mais recentemente precisamos usar no Site da Caelum. No mesmo lançamento da apostila do começo do mês que fizemos, tivemos um problema com os downloads das apostilas. Nossos PDFs, desde muito antigamente, ficam em um outro servidor Apache puro (sem Java, Rails etc) que apenas servia os milhares de downloads diários. Mas no dia do lançamento da apostila de Rails 3, nosso servidor de downloads não aguentou. E por alguns instantes passou a negar alguns requests de download. Logo depois desse episódio, passamos a servir os PDFs também pelo GAE, usando o novo serviço de BlobStore deles. O Datastore normal tem restrições quanto ao tamanho das entidades (no máximo 1 MB). Para servir arquivos grandes, eles disponibilizam o BlobStore, com ‘limit’ de 2GB no tamanho de cada Blob. Fazer o upload é fácil... @sergio_caelum | Caelum | QCon São Paulo 2010
    • BlobStore Primeiro passo é um fazer um formulário que tenha um input file. A URL de upload vai ser obtida direto do BlobStore... @sergio_caelum | Caelum | QCon São Paulo 2010
    • BlobStore ... o parâmetro passado é a URL pra onde o BlobStore redireciona após o salvar o upload. @sergio_caelum | Caelum | QCon São Paulo 2010
    • BlobStore ... nessa URL, podemos recuperar a Key associada a esse Blob uploadado... @sergio_caelum | Caelum | QCon São Paulo 2010
    • BlobStore E, por último, na Servlet de download, mandamos o BlobStore servir nosso blob (pela chave) diretamente no response. Não precisa abrir o arquivo, buscar, carregar na memória... nada. É simples e efetivo. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Conclusão... @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade, Disponibilidade - Escalabilidade infinita e Disponibilidade com terceirização da infra e da dor de cabeça
    • Escalabilidade, Disponibilidade Elasticidade e baixo custo - Elasticidade me permite atender picos de acesso e momentos de inatividade sem desperdício, pagando (pouco) apenas pelo que uso
    • Escalabilidade, Disponibilidade Elasticidade e baixo custo Serviços prontos - Serviços fantásticos e prontos como Datastore, Tasks, Memcache, Envio de e-mails, Blobstore, Autenticação etc; e outros, como processamento de imagens, envio e recebimento de XMPP @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade, Disponibilidade Elasticidade e baixo custo Serviços prontos Limitações e lock-in O ambiente do AppEngine é fastástico. Mudar o Caelum.com.br para lá, no começo, foi uma decisão para possibilitar estudar o novo ambiente. Com o tempo, percebemos que foi uma das melhores decisões arquiteturais que tomamos. As vantagens do GAE compensam muito algumas poucas desvantagens. E, muitas vezes, o que aparenta ser uma desvantagem acaba nos forçando a programar direito e evitar problemas futuros. Mas temos que aprender a lidar com as limitações do ambiente, em especial o tradeoff com relação a performance e confiabilidade. O objetivo da palestra foi mostrar o caminho das pedras para quem pretende entrar no GAE, economizar algumas horas de estudo. No fim, acabamos escrevendo muito código voltado pra infra do GAE o que pode trazer o vendor lock-in. @sergio_caelum | Caelum | QCon São Paulo 2010
    • Escalabilidade, Disponibilidade Elasticidade e baixo custo Serviços prontos Limitações e lock-in Palestra “O Impacto do Design na sua arquitetura” Com Paulo Silveira, amanhã à 13h10 Mas evite espalhar o código específico, um bom design permite uma boa troca de arquitetura! (não perca amanhã a palestra do Paulo Silveira sobre o assunto!) @sergio_caelum | Caelum | QCon São Paulo 2010
    • Sérgio Lopes sergio.lopes @caelum.com.br @sergio_caelum Obrigado! @sergio_caelum | Caelum | QCon São Paulo 2010