Palestra sobre case apresentado no QConSP 2013, com uma diversidade de produtos da plataforma Google e como endereçamos requisitos tradicionais de Enterprise Apps na plataforma.
2. Quem sou eu?!
● Bacharel Análise de
Sistemas PUC-
Campinas
● Arquiteto de Sistemas
● Especializando-se em
tecnologias Cloud
● Recém-carioca!ghconcon
@gconcon
gustavoc@ciandt.com
3. ● Fundada em 1995 (18 anos)
● Ofertas de Cloud Computing
(Google/Amazon /
Salesforce Partner)
● Application Development &
Management / SAP & BI /
Mobile …
● Cresce numa taxa média de
40% ao ano! Desde sua
fundação.
● Recrutando talentos!
Sobre a CI&T
6. ● Infra-estrutura complexa e sistemas
legados (JEE 1.3, Oracle, DB2, WebSphere
5 e 7)
● Alto custo com manutenção da infra
● Grande parte do processamento
backoffice no Mainframe (COBOL Batch e
COBOL CICS)
Contexto tecnológico
7. ● Já era cliente do Google Apps for Business
(E-Mail, Calendar, Docs, Sites)
● Decisão do Move to the Cloud por redução
de custos e complexidade de suporte
● Natural escolha do Google AppEngine
Contexto tecnológico
18. ● Dados gerados na núvem
● Processados no backoffice (Mainframe)
● Retorno do processamento para o cliente
● Plano futuro de remover dependência do
Mainframe
Requisito
20. ● Não há conexão Núvem > Rede Local
(Quebra de DMZ), sempre o local consume
a núvem
● Registros já separados para
processamento (Evita overhead de
identificar o que mudou)
● Dados enfileirados de maneira escalável
Uso do TaskQueue (Pull Queue)
23. ● Conjunto Spring Batch + Control-M
(Scheduler)
● Autenticação com a núvem via OAuth
● Consumo do TaskQueue
● Envio do processamento ao COBOL CICS
(online) - Regra de negócio!
Aplicação Replicadora
24. ● Processamentos com erro são devolvidos
na hora
● ATOMICIDADE da transação MANUAL!
Não há suporte a XA
Última linha do processo é excluir a Task
Aplicação Replicadora
26. ● Replicação de dados Online (Quente) do
DB2 Mainframe para o Oracle via Oracle
GoldenGate
● Replicação via UNDO tablespace, baixo
custo na origem!
● Timestamp de replicação (Temos o Delta!)
Redução da dependência do
Mainframe
28. ● Uso do Remote API do AppEngine (Acesso
direto ao Datastore)
● Conexão JDBC/OAuth com CloudSQL
● Liberação do registro ou críticas de
processamento ao usuário
● Throughput atende!
~2k registros/seg = 4mb/seg
Replicação - Resultado do
processamento
30. ● Dados corporativos, comuns a todas as
aplicações
● Rastreabilidade e consistência das
informações
Requisito
31. ● Cada App possui seu próprio domínio de
dados (Datastore e/ou CloudSQL)
● Quem produz o dado é responsável por
ele
● Dados comuns (corporativos) centralizados
Solução
32. App com serviços corporativos, centralizadora dos dados
(domínio) em todo ecossistema AppEngine
● Conteúdo REST
● Autenticação via OAuth
● Domínios como consulta de CEP,
Empresas, UF, Profissão...
● Cacheable, baixíssimo custo
(Latência de rede não é problema)
● Basicamente pagamos o Storage
(1.2GB)
33. ● Gestão de volume, autorizações e
escalabilidade no contexto específico da
app corporativa
● Dashboard do AppEngine específico,
gestão mais eficaz
Controle da aplicação corporativa
36. ● Endereços na base armazenados como
“Avenida Paulista, 1000, São Paulo”
● Conversão para Latitude/Longitude
● Google Geocoding API
Geocodificação dos endereços
37. ● Limite de até 2,5k conversões por dia (100k
para clientes premier ;) )
● Free
● Só pode usar se plotar o resultado no
Mapa do Google Maps!!!
Geocodificação dos endereços
39. ● Janeiro de 2011!
● Ferramenta promissora da Google, recém
lançada!
● Em fase Experimental!
“É o risco da inovação!”
Cenário
40. Google Fusion Tables
● Cláusulas e funções como ORDER
BY DISTANCE, CIRCLE, INTERSECTs
● Performance OK! Escalabilidade
não tão ok...
Bateria Throughput %90 Samples
1 5 req/seg ~1 seg 70k
2 8,3 req/seg 3.3 segs 250k
41. ● Mudanças constantes no comportamento
da API (App parada em produção)
● API foi descontinuada 6 meses depois
● Hoje ainda existe, API reestruturada
“É o risco da inovação!”
Google Fusion Tables
42. Migramos para o Google CloudSQL
● É o MySQL na núvem
● Disponível (na fase oficial) desde
Jun/2012
● Instâncias de máquinas com até
16GB de RAM e até 100GB de disco
● Replicação automática, síncrona ou
assíncrona, around the globe!
● Suporte a consultas geospaciais
nativas do MySQL :)
43. ● MySQL possui suporte a datatypes de
geometria, GEOMETRY, POINT, CURVE,
POLYGON
OpenGIS Geometry Model
● Tabelas do tipo MyISAM, InnoDB não tem
suporte!
● Índice R-Tree para consulta geométrica
CREATE SPATIAL INDEX sp_index ON mytable (g);
How it works?!
44. ● O conceito permite buscas indexadas
retornando se o ponto está dentro de um
polígono (MBRWithin / MBRContains)
● Ou se polígonos se cruzam
● Não dá pra indexar busca por distância
How it works?!
45. ● O jeito é montar um polígono e obter os
pontos que estão dentro!
● E depois calcular a distância “na mão”
( 6371 * acos( cos( radians(Latitude) ) * cos( radians( X
(LATLONG) ) ) * cos( radians( Y(LATLONG) ) - radians
(Longitude) ) + sin( radians(Latitude) ) * sin( radians( X
(LATLONG) ) ) ) ) AS DISTANCE !!!!!!
How it works?!
49. ● O CloudSQL trabalha nativamente com
replicação around the globe.
● Configurável: Síncrona ou Assíncrona
● Síncrona: Insert/Update/Delete são
replicados dentro do statement
● Assíncrona: Insert/Update/Delete são
replicados fora do statement
Ponto interessante sobre o
CloudSQL
50. ● A percepção de performance é notável,
fizemos o teste:
○ Síncrono: 10K inserts com commit de 500 em 500
10 segundos
○ Assíncrono: 10k inserts com commit de 500 em
500
5 segundos
Ponto interessante sobre o
CloudSQL
51. ● Recomendação:
○ Configure assíncrono sempre que possível!
Acredito que atende 99% dos projetos que
tenham constantes atualizações de dados
Ponto interessante sobre o
CloudSQL
53. ● Resumable Uploads
● Espaço ilimitado
● Billing por volume armazenado + network
traffic
Google CloudStorage
54. ● API de integração no AppEngine SDK
(Blobstore API)
blobstoreService.createUploadUrl("/uploaded",
UploadOptions uploadOptsWithBucketName);
blobstoreService.getUploads(request); //File info
(BlobKey)
Uploading files
55. Exportação da base, de forma
analítica (~600.000 registros) em CSV
Requisito
56. ● Uso de PushQueues (Public/Subscribe)
● Instâncias backend não têm limite de
tempo de processamento
● CloudStorage usado como repositório dos
arquivos gerados
Solução
58. ● A SDK não implementa 100% da
especificação
● Mas calma, é quase lá…
AppEngine SDK não é JEE
59. ● Java Data Objects (JDO)
● Java Persistence API (JPA)
● Java Server Faces (JSF) 1.1 - 2.0
● Java Server Pages (JSP) + JSTL
● Java Servlet API 2.4
● JavaBeans™ Activation Framework (JAF)
● Java Architecture for XML Binding (JAXB)
● Java API for XML Web Services (JAX-WS)
● JavaMail
● XML processing APIs including DOM, SAX, and XSLT
Componentes mais comuns
suportados
60. ● Enterprise Java Beans (EJB)
● JAX-RPC
● Java Database Connectivity (JDBC)
● Java EE™ Connector Architecture (JCA)
● Java Management Extensions (JMX)
● Java Message Service (JMS)
● Java Naming and Directory Interface (JNDI)
● Remote Method Invocation (RMI)
Tentativa de categorizar o que funciona ou não::
https://code.google.
com/p/googleappengine/wiki/WillItPlayInJava
O que não é compatível
61. ● Spring Framework 3.2
● Hibernate 4.2 (Apenas com CloudSQL)
● JSF 2.1 + Primefaces 3.5 (Precisamos de alguns
workarounds)
● iText 2.1.7 (Adaptado)
● Objectify 3.1
O que usamos
62. ● Framework ORM para Datastore
● Encapsula acessos através de annotations com a
mesma nomenclatura do JPA (@Transaction, @Entity)
e outras extensões
● Cache automático usando o MemCache
@Entity
class Car {
@Id String vin; // Can be Long, long, or String
String color;
}
ofy().save().entity(new Car("123123", "red")).now();
Car c = ofy().load().type(Car.class).id("123123").get();
ofy().delete().entity(c);
Objectify
63. Alguns cuidados ao usar Spring
Framework
● Tempo de warmup máximo de 60 segundos
● Evite ou reduza o uso de <component-scan>
● Evite ou reduza o uso de @AutoWire (Principalmente
by-type)
● Desabilite o XML Validation em produção
● lazy-init=”true” na declaração dos Beans
https://developers.google.
com/appengine/articles/spring_optimization
64. Nosso warmup
● 250 beans (@Component)
● Usando component-scanning = Estourou os 60 segs
com ~160 Beans
● Warmup de 38 segundos apenas removendo o
component-scanning + lazy-init
67. ● Fácil integração Jenkins + AppCfg para
deployment automatizado
● Baixíssimo custo para termos ambientes
de Integration + QA + UAT
● Gastamos hoje US$ 400,00 com:
○ Amazon: Máquina Jenkins + Sonar + Nexus + RDS
(Sonar)
○ Ambientes AppEngine e CloudSQL (Uma app p/
cada ambiente)
Deployment ágil
68. ● Versão atribuída na build via Maven
Release Plugin dentro do appengine-web.
xml
● Permite deployment e acesso a versões
separadas no ambiente
http://1-2-1.minhaapp.appspot.com
● Usuário homologa defeitos em “pré-
produção” antes de liberá-la
Versionamento
69. ● Ambientes na mesma infra de produção
● Testes de carga/stress não necessitam
usar produção
● AppEngine Dashboard extremamente útil
Architecture Validation
71. ● Cliente extremamente “comprado” na
tecnologia
● A conversa de novos projetos inicia com
“Faz sentido fazermos no AppEngine?”
● Segundo a Google, é o cliente que
mais usa a suite de produtos
Google Enterprise no Brasil!
Satisfação geral!
72. ● Hoje a SulAmérica gasta com todas as
aplicações + CloudStorage + CloudSQL +
Ambientes QA/UAT/PRD
+ Premier Support
Em média US$ 1600,00
● Uma máquina de servidor de aplicação
tradicional, com backup e hospedada no
fornecedor:
~ US$ 30.000,00
E o principal… CUSTO!