Upload
gustavo-concon
View
236
Download
1
Embed Size (px)
DESCRIPTION
Google AppEngine: 3 anos de estrada no case com a maior abrangência de produtos usando a plataforma no Brasil
Citation preview
Google AppEngine:3 anos de estrada no case com a maior
abrangência de produtos usando a plataforma no Brasil
CloudSQL
Cloud Storage
Task Queue (Pull Queues)
Backends
Datastore
Task Queue (Push Queues)Remote API
Como tudo começou...
● Infra-estrutura complexa e sistemas legados
● Alto custo com manutenção da infra
● Grande parte do processamento backoffice no Mainframe (COBOL Batch e COBOL CICS)
Contexto tecnológico
● Tornou-se 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
Em 2010...
Maturidade
(JSP + jQuery)Spring
(Objectify)
Datastore
(JSF + Primefaces)Spring
(JPA + Hibernate)
CloudSQL
Visão Geral da Arquitetura
Visão Geral da Arquitetura
Integração com a núvem
Descida dos dados gerados na núvem
Para o usuário
Aplicação Replicadora
Redução da dependência do Mainframe
Subida do resultado do processamento
Governança dos Dados
● Dados corporativos, comuns a todas as aplicações
● Rastreabilidade e consistência das informações
O Problema
App com serviços corporativos, centralizadora dos dados (domínio) em todo ecossistema AppEngine
● Domínios como consulta de CEP,
Empresas, UF, Profissão...
● Cacheable, baixíssimo custo
(Latência de rede não é problema)
● Gestão de volume e
permissionamento
● Dashboard específico
Busca Geolocalizada por proximidade
O Objetivo
● 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
Mas como fazer as buscas por proximidade??
● Janeiro de 2011!
● Ferramenta promissora da Google, recém lançada!
● Em fase Experimental!
“É o risco da inovação!”
Cenário
Google Fusion Tables
● Cláusulas e funções como ORDER
BY DISTANCE, CIRCLE, INTERSECTs
select local from Locais
where CIRCLE(<latlong>, <raio>)
order by distance;
● 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
Migramos para o Google CloudSQL
● É o MySQL na núvem
● Disponível (na fase oficial) desde
Jun/2012
● Replicação automática, síncrona ou
assíncrona, around the globe!
● Suporte a consultas geospaciais
nativas do MySQL :)
● MySQL possui suporte a datatypes de geometria, GEOMETRY, POINT, CURVE, POLYGONOpenGIS Geometry Model
● Tabelas do tipo MyISAM, InnoDB não tem suporte!
● Índice R-Tree para consulta geométricaCREATE SPATIAL INDEX sp_index ON mytable (g);
How it works?!
● O conceito permite buscas indexadas retornando se o ponto está dentro de um polígono (MBRWithin / MBRContains)
How it works?!
Mas eu preciso do CÍRCULO!!!
( 6371 * acos( cos( radians(Latitude) ) * cos( radians( X(LATLONG) ) ) * cos( radians( Y(LATLONG) ) - radians(Longitude) ) + sin( radians(Latitude) ) * sin( radians( X(LATLONG) ) ) ) ) AS DISTANCE !!!!!!
Faça uma limonada...
SELECT *
FROM ( SELECT *, ( 6371 * acos( cos( radians(1) ) * cos(
radians( X(LATLONG) ) ) * cos( radians( Y(LATLONG) ) - radians(1.1) ) + sin( radians(1) ) * sin( radians( X(LATLONG) ) ) ) ) AS DISTANCE
FROM MAPA_ATENDIMENTO
WHERE MBRWithin( LATLONG, Envelope( GeomFROMText( 'LineString( X Y , X Y)'))
) inner
WHERE inner.DISTANCE <= Z
Show me the code!!
● 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
Pontos interessantes sobre o CloudSQL
● 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
5005 segundos
Pontos interessantes sobre o CloudSQL
Upload & Download de Arquivos
● Resumable Uploads
● Espaço ilimitado
Google CloudStorage
● API de integração no AppEngine SDK (Blobstore API)
blobstoreService.createUploadUrl("/uploaded",
UploadOptions uploadOptsWithBucketName);
blobstoreService.getUploads(request); //File info (BlobKey)
Uploading files
Exportação da base, de forma analítica (~600.000 registros) em CSV
Requisito
GAE tem limite de 60 s por request!
Solução
PushQueue
ApplicationPushQueue
Backend instanceBackend instance
Backend instanceCloud
Storage
DATASTORE
Lições aprendidas
● A SDK não implementa 100% da especificação
● Mas calma, é quase lá…
AppEngine SDK não é JEE
● 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
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
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
CloudSQL
Cloud Storage
Task Queue (Pull Queues)
Backends
Datastore
Task Queue (Push Queues)Remote API
Pra fechar!
● Cliente satisfeito com a plataforma
"Onde fizer sentido, vamos migrar pra núvem"
Satisfação geral!
● Uma máquina de servidor de aplicação tradicional (hosting):~ US$ 30.000,00 mês
● Todas as aplicações + CloudStorage + CloudSQL + Ambientes QA/UAT/PRD+ Premier Support
Em média US$ 1600,00
E o principal… CUSTO!
Obrigado!