SlideShare a Scribd company logo
1 of 120
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

More Related Content

Viewers also liked

Construindo uma Aplicação PHP à Prova de Balas
Construindo uma Aplicação PHP à Prova de BalasConstruindo uma Aplicação PHP à Prova de Balas
Construindo uma Aplicação PHP à Prova de BalasRafael Jaques
 
Asterisk Uma SoluçãO Em Pabx Ip
Asterisk   Uma SoluçãO Em Pabx IpAsterisk   Uma SoluçãO Em Pabx Ip
Asterisk Uma SoluçãO Em Pabx IpCamila Verônica
 
Asterisk O Pabx Livre Para Voip
Asterisk   O Pabx Livre Para VoipAsterisk   O Pabx Livre Para Voip
Asterisk O Pabx Livre Para VoipGilberto Sudre
 
Redes VoIP - O Futuro da Telefonia
Redes VoIP - O Futuro da TelefoniaRedes VoIP - O Futuro da Telefonia
Redes VoIP - O Futuro da TelefoniaFrederico Madeira
 

Viewers also liked (6)

Instalação do Asterisk
Instalação do AsteriskInstalação do Asterisk
Instalação do Asterisk
 
Asterisk Voice Mail
Asterisk Voice MailAsterisk Voice Mail
Asterisk Voice Mail
 
Construindo uma Aplicação PHP à Prova de Balas
Construindo uma Aplicação PHP à Prova de BalasConstruindo uma Aplicação PHP à Prova de Balas
Construindo uma Aplicação PHP à Prova de Balas
 
Asterisk Uma SoluçãO Em Pabx Ip
Asterisk   Uma SoluçãO Em Pabx IpAsterisk   Uma SoluçãO Em Pabx Ip
Asterisk Uma SoluçãO Em Pabx Ip
 
Asterisk O Pabx Livre Para Voip
Asterisk   O Pabx Livre Para VoipAsterisk   O Pabx Livre Para Voip
Asterisk O Pabx Livre Para Voip
 
Redes VoIP - O Futuro da Telefonia
Redes VoIP - O Futuro da TelefoniaRedes VoIP - O Futuro da Telefonia
Redes VoIP - O Futuro da Telefonia
 

Similar to Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine - Sergio Lopes - QCon SP 2010

Transformando a ti com cloud computing e virtualização
Transformando a ti com cloud computing e virtualizaçãoTransformando a ti com cloud computing e virtualização
Transformando a ti com cloud computing e virtualizaçãoDarlan Segalin
 
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud Computing
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud ComputingPaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud Computing
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud ComputingCI&T
 
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...Rio Info
 
Pangea - Plataforma digital com Google Cloud Platform
Pangea - Plataforma digital com Google Cloud PlatformPangea - Plataforma digital com Google Cloud Platform
Pangea - Plataforma digital com Google Cloud PlatformAndré Paulovich
 
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...Gustavo Concon
 
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...iMasters
 
Matando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaMatando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaJosé Roberto Araújo
 
Apresentação Comercial Tecla Internet
Apresentação Comercial Tecla InternetApresentação Comercial Tecla Internet
Apresentação Comercial Tecla InternetTecla Internet
 
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azure
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on AzureTDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azure
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azuretdc-globalcode
 
Service Mesh de microserviços com Istio e Envoy
Service Mesh de microserviços com Istio e EnvoyService Mesh de microserviços com Istio e Envoy
Service Mesh de microserviços com Istio e EnvoyVinícius de Paula
 
Guião demotécnica
Guião demotécnicaGuião demotécnica
Guião demotécnicaSilvio Dias
 
Guiao demotecnica
Guiao demotecnicaGuiao demotecnica
Guiao demotecnicaSilvio Dias
 
DevOps, por onde começar
DevOps, por onde começarDevOps, por onde começar
DevOps, por onde começarAdriano Tavares
 
MIT - Estudo de Caso utilizando Cloud & DevOps
MIT - Estudo de Caso utilizando Cloud & DevOps  MIT - Estudo de Caso utilizando Cloud & DevOps
MIT - Estudo de Caso utilizando Cloud & DevOps Caio Candido
 
Phprs meetup - deploys automatizados com gitlab
Phprs   meetup - deploys automatizados com gitlabPhprs   meetup - deploys automatizados com gitlab
Phprs meetup - deploys automatizados com gitlabJackson F. de A. Mafra
 
Chalice.pdf
Chalice.pdfChalice.pdf
Chalice.pdfPyCaxias
 
SimulaRSO - Simulador de Recursos de Sistemas Operacionais
SimulaRSO - Simulador de Recursos de Sistemas OperacionaisSimulaRSO - Simulador de Recursos de Sistemas Operacionais
SimulaRSO - Simulador de Recursos de Sistemas OperacionaisCaio Ribeiro Pereira
 

Similar to Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine - Sergio Lopes - QCon SP 2010 (20)

Transformando a ti com cloud computing e virtualização
Transformando a ti com cloud computing e virtualizaçãoTransformando a ti com cloud computing e virtualização
Transformando a ti com cloud computing e virtualização
 
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud Computing
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud ComputingPaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud Computing
PaaS (Plataforma Como Serviço) é o Verdadeiro Pote de Ouro de Cloud Computing
 
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...
Rio Info 2010 - Oficina - Computacao em nuvem do ponto de vista empresarial -...
 
AWS re:Invent 2019
AWS re:Invent 2019AWS re:Invent 2019
AWS re:Invent 2019
 
Pangea - Plataforma digital com Google Cloud Platform
Pangea - Plataforma digital com Google Cloud PlatformPangea - Plataforma digital com Google Cloud Platform
Pangea - Plataforma digital com Google Cloud Platform
 
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...
CI&T DevDay BH 2013 - Google AppEngine: 3 anos de estrada no case com a maior...
 
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...
[JS EXPERIENCE 2018] Do jQuery aos microfrontends: os desafios de manter uma ...
 
Matando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejistaMatando web forms e modernizando um grande varejista
Matando web forms e modernizando um grande varejista
 
Apresentação Comercial Tecla Internet
Apresentação Comercial Tecla InternetApresentação Comercial Tecla Internet
Apresentação Comercial Tecla Internet
 
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azure
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on AzureTDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azure
TDC2018SP | Trilha Arq .Net - Serverless Reactive Programming on Azure
 
Service Mesh de microserviços com Istio e Envoy
Service Mesh de microserviços com Istio e EnvoyService Mesh de microserviços com Istio e Envoy
Service Mesh de microserviços com Istio e Envoy
 
Guião demotécnica
Guião demotécnicaGuião demotécnica
Guião demotécnica
 
Guiao demotecnica
Guiao demotecnicaGuiao demotecnica
Guiao demotecnica
 
Webinar DevOps - Encontros Ágeis
Webinar DevOps - Encontros ÁgeisWebinar DevOps - Encontros Ágeis
Webinar DevOps - Encontros Ágeis
 
DevOps, por onde começar
DevOps, por onde começarDevOps, por onde começar
DevOps, por onde começar
 
MIT - Estudo de Caso utilizando Cloud & DevOps
MIT - Estudo de Caso utilizando Cloud & DevOps  MIT - Estudo de Caso utilizando Cloud & DevOps
MIT - Estudo de Caso utilizando Cloud & DevOps
 
Phprs meetup - deploys automatizados com gitlab
Phprs   meetup - deploys automatizados com gitlabPhprs   meetup - deploys automatizados com gitlab
Phprs meetup - deploys automatizados com gitlab
 
Lets cloud presentation
Lets cloud presentationLets cloud presentation
Lets cloud presentation
 
Chalice.pdf
Chalice.pdfChalice.pdf
Chalice.pdf
 
SimulaRSO - Simulador de Recursos de Sistemas Operacionais
SimulaRSO - Simulador de Recursos de Sistemas OperacionaisSimulaRSO - Simulador de Recursos de Sistemas Operacionais
SimulaRSO - Simulador de Recursos de Sistemas Operacionais
 

More from Caelum

Performance Web além do carregamento
Performance Web além do carregamentoPerformance Web além do carregamento
Performance Web além do carregamentoCaelum
 
Desafios de Performance Web - BrazilJS
Desafios de Performance Web - BrazilJSDesafios de Performance Web - BrazilJS
Desafios de Performance Web - BrazilJSCaelum
 
Performance na web: o modelo RAIL e outras novidades
Performance na web: o modelo RAIL e outras novidadesPerformance na web: o modelo RAIL e outras novidades
Performance na web: o modelo RAIL e outras novidadesCaelum
 
Progressive Web Apps: o melhor da Web appficada
Progressive Web Apps: o melhor da Web appficadaProgressive Web Apps: o melhor da Web appficada
Progressive Web Apps: o melhor da Web appficadaCaelum
 
Tudo que você precisa saber sobre picture e srcset
Tudo que você precisa saber sobre picture e srcsetTudo que você precisa saber sobre picture e srcset
Tudo que você precisa saber sobre picture e srcsetCaelum
 
Como o HTTP/2 vai mudar sua vida
Como o HTTP/2 vai mudar sua vidaComo o HTTP/2 vai mudar sua vida
Como o HTTP/2 vai mudar sua vidaCaelum
 
Métricas e a automatização do controle de qualidade
Métricas e a automatização do controle de qualidadeMétricas e a automatização do controle de qualidade
Métricas e a automatização do controle de qualidadeCaelum
 
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio Lopes
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio LopesHTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio Lopes
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio LopesCaelum
 
Offline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesOffline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesCaelum
 
Design Responsivo - MobCamp 2014
Design Responsivo - MobCamp 2014Design Responsivo - MobCamp 2014
Design Responsivo - MobCamp 2014Caelum
 
Além do responsive design: a mudança de paradigma do design adaptativo e os m...
Além do responsive design: a mudança de paradigma do design adaptativo e os m...Além do responsive design: a mudança de paradigma do design adaptativo e os m...
Além do responsive design: a mudança de paradigma do design adaptativo e os m...Caelum
 
Por trás dos frameworks e além do reflection
Por trás dos frameworks e além do reflectionPor trás dos frameworks e além do reflection
Por trás dos frameworks e além do reflectionCaelum
 
Otimizações de Performance Web: Desafios do Mundo Mobile
Otimizações de Performance Web: Desafios do Mundo MobileOtimizações de Performance Web: Desafios do Mundo Mobile
Otimizações de Performance Web: Desafios do Mundo MobileCaelum
 
Introducao a inteligencia artificial na educacao
Introducao a inteligencia artificial na educacaoIntroducao a inteligencia artificial na educacao
Introducao a inteligencia artificial na educacaoCaelum
 
Otimizando o time to market - do zero a produção em poucas iterações
Otimizando o time to market - do zero a produção em poucas iteraçõesOtimizando o time to market - do zero a produção em poucas iterações
Otimizando o time to market - do zero a produção em poucas iteraçõesCaelum
 
All you need to know about JavaScript loading and execution in the browser - ...
All you need to know about JavaScript loading and execution in the browser - ...All you need to know about JavaScript loading and execution in the browser - ...
All you need to know about JavaScript loading and execution in the browser - ...Caelum
 
Wsrest 2013
Wsrest 2013Wsrest 2013
Wsrest 2013Caelum
 
Design Responsivo por uma Web única
Design Responsivo por uma Web únicaDesign Responsivo por uma Web única
Design Responsivo por uma Web únicaCaelum
 
Os Caminhos de uma Estratégia Mobile
Os Caminhos de uma Estratégia MobileOs Caminhos de uma Estratégia Mobile
Os Caminhos de uma Estratégia MobileCaelum
 
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Caelum
 

More from Caelum (20)

Performance Web além do carregamento
Performance Web além do carregamentoPerformance Web além do carregamento
Performance Web além do carregamento
 
Desafios de Performance Web - BrazilJS
Desafios de Performance Web - BrazilJSDesafios de Performance Web - BrazilJS
Desafios de Performance Web - BrazilJS
 
Performance na web: o modelo RAIL e outras novidades
Performance na web: o modelo RAIL e outras novidadesPerformance na web: o modelo RAIL e outras novidades
Performance na web: o modelo RAIL e outras novidades
 
Progressive Web Apps: o melhor da Web appficada
Progressive Web Apps: o melhor da Web appficadaProgressive Web Apps: o melhor da Web appficada
Progressive Web Apps: o melhor da Web appficada
 
Tudo que você precisa saber sobre picture e srcset
Tudo que você precisa saber sobre picture e srcsetTudo que você precisa saber sobre picture e srcset
Tudo que você precisa saber sobre picture e srcset
 
Como o HTTP/2 vai mudar sua vida
Como o HTTP/2 vai mudar sua vidaComo o HTTP/2 vai mudar sua vida
Como o HTTP/2 vai mudar sua vida
 
Métricas e a automatização do controle de qualidade
Métricas e a automatização do controle de qualidadeMétricas e a automatização do controle de qualidade
Métricas e a automatização do controle de qualidade
 
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio Lopes
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio LopesHTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio Lopes
HTTP/2, SPDY e Otimizações Web - Front In Maceió 2014 - Sérgio Lopes
 
Offline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesOffline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio Lopes
 
Design Responsivo - MobCamp 2014
Design Responsivo - MobCamp 2014Design Responsivo - MobCamp 2014
Design Responsivo - MobCamp 2014
 
Além do responsive design: a mudança de paradigma do design adaptativo e os m...
Além do responsive design: a mudança de paradigma do design adaptativo e os m...Além do responsive design: a mudança de paradigma do design adaptativo e os m...
Além do responsive design: a mudança de paradigma do design adaptativo e os m...
 
Por trás dos frameworks e além do reflection
Por trás dos frameworks e além do reflectionPor trás dos frameworks e além do reflection
Por trás dos frameworks e além do reflection
 
Otimizações de Performance Web: Desafios do Mundo Mobile
Otimizações de Performance Web: Desafios do Mundo MobileOtimizações de Performance Web: Desafios do Mundo Mobile
Otimizações de Performance Web: Desafios do Mundo Mobile
 
Introducao a inteligencia artificial na educacao
Introducao a inteligencia artificial na educacaoIntroducao a inteligencia artificial na educacao
Introducao a inteligencia artificial na educacao
 
Otimizando o time to market - do zero a produção em poucas iterações
Otimizando o time to market - do zero a produção em poucas iteraçõesOtimizando o time to market - do zero a produção em poucas iterações
Otimizando o time to market - do zero a produção em poucas iterações
 
All you need to know about JavaScript loading and execution in the browser - ...
All you need to know about JavaScript loading and execution in the browser - ...All you need to know about JavaScript loading and execution in the browser - ...
All you need to know about JavaScript loading and execution in the browser - ...
 
Wsrest 2013
Wsrest 2013Wsrest 2013
Wsrest 2013
 
Design Responsivo por uma Web única
Design Responsivo por uma Web únicaDesign Responsivo por uma Web única
Design Responsivo por uma Web única
 
Os Caminhos de uma Estratégia Mobile
Os Caminhos de uma Estratégia MobileOs Caminhos de uma Estratégia Mobile
Os Caminhos de uma Estratégia Mobile
 
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
Porque você deveria usar CDI nos seus projetos Java! - JavaOne LA 2012 - Sérg...
 

Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine - Sergio Lopes - QCon SP 2010

  • 1. Mitos e verdades do cloud do Google: 1 ano de experiências no AppEngine @sergio_caelum | Caelum | QCon São Paulo 2010
  • 2. 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
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. #1 Ambiente de Dev Primeiro ponto: Ambiente de Dev @sergio_caelum | Caelum | QCon São Paulo 2010
  • 21. 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
  • 22. 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
  • 23. #2 Fácil Gerenciamento Segundo ponto: recursos para gerenciamento remoto da aplicação de modo simples @sergio_caelum | Caelum | QCon São Paulo 2010
  • 24. Painel de Controle Há um completo Painel de Controle em http://appengine.google.com @sergio_caelum | Caelum | QCon São Paulo 2010
  • 25. 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
  • 26. 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
  • 27. Painel de Controle Data Viewer - Observar os dados, editá-los, executar queries no DataStore. @sergio_caelum | Caelum | QCon São Paulo 2010
  • 28. 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
  • 29. Versões No momento do deploy, edita-se um XML do GAE indicando a versão. @sergio_caelum | Caelum | QCon São Paulo 2010
  • 30. 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
  • 31. 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
  • 32. 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
  • 33. #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
  • 34. 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
  • 35. 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
  • 36. 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
  • 37. 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
  • 38. 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
  • 39. #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
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. Agora adicionamos a Entity @sergio_caelum | Caelum | QCon São Paulo 2010
  • 49. Aqui, temos uma busca de uma Entity a partir da chave dela (Key) @sergio_caelum | Caelum | QCon São Paulo 2010
  • 50. 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
  • 51. Modelamos nossa entidade usando um subset das anotações da JPA @sergio_caelum | Caelum | QCon São Paulo 2010
  • 52. E aqui inserimos o objeto Noticia usando o Objectify @sergio_caelum | Caelum | QCon São Paulo 2010
  • 53. 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
  • 54. Twig Outro framework alternativo é o Twig @sergio_caelum | Caelum | QCon São Paulo 2010
  • 55. 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
  • 56. 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
  • 57. 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
  • 58. 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
  • 59. 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
  • 60. #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
  • 61. 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
  • 62. Ao tentar persistir alguma coisa (com JPA, Objectify etc)... @sergio_caelum | Caelum | QCon São Paulo 2010
  • 63. ... o GAE lança uma Exception indicando a indisponibilidade do serviço. É bom estar preparado @sergio_caelum | Caelum | QCon São Paulo 2010
  • 64. 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
  • 65. O código para obter a instância do Cache usando JCache @sergio_caelum | Caelum | QCon São Paulo 2010
  • 66. 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
  • 67. Um exemplo prático: uma busca no DAO. @sergio_caelum | Caelum | QCon São Paulo 2010
  • 68. 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
  • 69. 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
  • 70. 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
  • 71. 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
  • 72. #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
  • 73. 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
  • 74. 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
  • 75. 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
  • 76. 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
  • 77. 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?
  • 78. 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
  • 79. 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
  • 80. #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
  • 81. 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
  • 82. 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
  • 83. Posso então processar outras coisas e voltar pra pegar a resposta depois. @sergio_caelum | Caelum | QCon São Paulo 2010
  • 84. 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
  • 85. 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
  • 86. Aqui um exemplo passando um parâmetro @sergio_caelum | Caelum | QCon São Paulo 2010
  • 87. Aqui um outro passando um corpo completo (payload) @sergio_caelum | Caelum | QCon São Paulo 2010
  • 88. 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
  • 89. ... 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
  • 90. 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
  • 91. 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
  • 92. Meu controller que responde na URL da Task (aqui usando sintaxe do VRaptor) @sergio_caelum | Caelum | QCon São Paulo 2010
  • 93. 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
  • 94. ... 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!
  • 95. 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
  • 96. 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
  • 97. 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
  • 98. #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
  • 99. 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
  • 100. 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
  • 101. 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
  • 102. Recebimento de e-mails ... e tratar o request como uma mensagem do JavaMail, sem segredo @sergio_caelum | Caelum | QCon São Paulo 2010
  • 103. 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
  • 104. 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
  • 105. 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
  • 106. 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
  • 107. Autenticação Google Mas podemos permitir qualquer usuário Google também, mudando o role para * @sergio_caelum | Caelum | QCon São Paulo 2010
  • 108. 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
  • 109. 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
  • 110. 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
  • 111. 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
  • 112. BlobStore ... nessa URL, podemos recuperar a Key associada a esse Blob uploadado... @sergio_caelum | Caelum | QCon São Paulo 2010
  • 113. 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
  • 114. Conclusão... @sergio_caelum | Caelum | QCon São Paulo 2010
  • 115. Escalabilidade, Disponibilidade - Escalabilidade infinita e Disponibilidade com terceirização da infra e da dor de cabeça
  • 116. 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
  • 117. 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
  • 118. 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
  • 119. 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
  • 120. Sérgio Lopes sergio.lopes @caelum.com.br @sergio_caelum Obrigado! @sergio_caelum | Caelum | QCon São Paulo 2010