Internet sem Drama
Enfrentando desafios diários!
@iuriandreazza
/iuri.andreazza
@iuriandreazza
- Travel Engineering @ Fabuloso Destino
- B.el em Ciência da Computação (Unisinos)
- Engenheiro de Software/Devops
- PHP,Python,Ruby,Java
- RBS/Zap Imóveis
- Geek
- Tech Crazy
- Early Adopter
Do começo
• Background
• Deploy de 3 em 3 meses
• Features requests semanais
• 5 camadas de processos para deploy
• Go live não agile
• O que fazer?
@iuriandreazza
/iuri.andreazza
Estrutura que havia
• Deploy somente com script (GMud)
• Sem acesso a PRD (mesmo sem nível de usuário ou logs)
• Scripts de banco somente executados por um DB oficial
• Somente atualizações não criticas durante o dia
• Qualquer mudança de médio ou grande porte deveria ser a noite.
@iuriandreazza
/iuri.andreazza
O que era realmente bom?
• Apoio dos DBAs
• Apoio da Infra em questões estruturais
• A necessidade de pensar bem antes de “Go Live”
• Ambientes bem estáveis
@iuriandreazza
/iuri.andreazza
O que era ruim?
• Dificuldade de liberar rapidamente uma versão do portal
• Resistência da equipe de infra-estrutura em aplicar patchs e
correções
• Grande dificuldade de se colocar algo rapidamente no ar.
@iuriandreazza
/iuri.andreazza
O que enfrentávamos?
• Necessidade de ajustar o negócio de forma rápida
• Necessidade de colocar rapidamente soluções novas ou correções
imediatas
• Desenvolvimento era todo Agile, infra não era
• Falta de processo e entendimento de como liberar o software do
portal
@iuriandreazza
/iuri.andreazza
PaaS/Cloud o que?????
• Analise:
• Ir para AWS - Amazon
• Ajustar Infra do datacenter local e tentar fazer o melhor possível
• Pesquisar e implementar um processo de deploy mais consigo e
mais rápido com a infra
• Começar a instigar soluções PaaS para a equipe, como
openstack, mesos ou openshift.
@iuriandreazza
/iuri.andreazza
Gestão de versão
• Entender como separar features
• Entender como quebrar em etapas entregáveis
• Criar metodologia no time e na infra-estrutura de como liberar
• Deploy-continuo consiste:
• Desenvolvimento com Testes (TDD, BDD)
• Facilidade de liberar uma versão nova sem downtime, ou com
processo preciso.
@iuriandreazza
/iuri.andreazza
@iuriandreazza
/iuri.andreazza
Time
release
branchesmasterhotfixes
1.0.0
2.0.0
dev
Inicio
Release
PRD BUG
featurebranches
Ontologia
New
Ecommerce
1.0.5
Atualiza
from
HOTFIX
2.0.1
X
Inicio
Release
GITFLOW
Infra 1.5
• Ajustar com a equipe de infra-estrutura para um deploy mais rápido
• Processo de Deploy maquina-a-maquina
• Scripts de banco que sejam incrementais e nunca quebrem o
software
• Liberação de regras para atualização de arquivos estáticos
@iuriandreazza
/iuri.andreazza
Infra 2.0
• Mover para a Amazon-AWS
• Assumir toda a gestão da infra
• Criar estrutura de deploy continuo usando Jenkins-CI
• Adicionar e remover maquinas on-the-fly conforme a necessidade
• Monitoramento avançado para uso do portal
@iuriandreazza
/iuri.andreazza
Penseimoves->ZAP
• Venda do penseimoveis para o ZAP
• 40 Milhões
• Ocorreu somente por causa do movimento para o Cloud e da
capacidade da equipe
• ZAP absorveu a tecnologia e a equipe e trocou o portao
penseimoveis pelo deles.
@iuriandreazza
/iuri.andreazza
Recortando Imagens on-the-go
• Problema:
• Imagens do portal do antigo penseimoveis.com.br estavam
estranhas
• Debug:
• As vezes os recortes eram entregues as vezes não
• As vezes as imagens vinham parcialmente criadas
• As vezes as imagens vinham coloridas e com “filtros" errados
@iuriandreazza
/iuri.andreazza
Achando o problema!
• Possíveis causas iniciais:
• Tempo de resposta durante a entrega
• Cache não sendo feito de forma correta (lado server)
• Headers de cache não sendo colocados
• Rede (3g/4g/Wifi/Ethernet …)
• Recortador "baleando"
@iuriandreazza
/iuri.andreazza
Estrutura que havia
• Recortador dividia recursos com a aplicação principal
• Tech-Stack: JAVA App + Glassfish Clusterizado 4.1 (App Server),
varnish(webcache),apache(lb)
• Datacenter RBS (4 Maquinas 32Gb)
• 8Cores 2.3Ghz (Blades)
• NAS - HDD SCSI/SSD
• Link dedicado
@iuriandreazza
/iuri.andreazza
Métricas (Stack-Java)
segundos
0
0,75
1,5
2,25
3
RPM
500 1000 4000 9000 20000
Tempo de Resp. IO/W
Mb
0
100
200
300
400
RPM
500 1000 4000 9000 20000
MEM
@iuriandreazza
/iuri.andreazza
Desafios
• Java-NIO
• Causava problemas de IO e drop da JVM em alguns casos de
concorrência
• IO Wait (FS, NAS vs MemFS)
• Espaço vs Escalabilidade vs Nível Cache
• Hang Glassfish
• Refatoring constante do codigo em busca de melhorias
@iuriandreazza
/iuri.andreazza
Pragmatico!
• Qual tech usar?
• Python?
• comunidade bastante ativa
• boa lib de manipulação de imagens “Pylon"
• bom micro-framework web (@flask)
• Simples de usar, pouco código necessário para fazer o mesmo
• Simples de fazer deploy
@iuriandreazza
/iuri.andreazza
Stack-Py
• Usando Pyhton
• PIL
• flask
• Setup (infra-estrutura)
• Varnish
• Nginx+
• 4 instancias flask
@iuriandreazza
/iuri.andreazza
Stack-Py
import sys

import pense_lib

from flask import Flask

from flask import request



import hmac

import hashlib

import requests

import base64

import time

import datetime



app = Flask(__name__)

app.config.from_pyfile('flaskapp.cfg')

@app.route('/images/<path:file_path>')

def static_asset(file_path):
w = request.args.get('w', None)

h = request.args.get('h', None)

fit = request.args.get('fit', "f")

env_rec = request.args.get('e', "production")

#tratando de recorte

center = request.args.get('c', "a")

if "," in center:

center = center.split(",")



return pense_lib.processRequest(file_path, w, h, fit, center,
env_rec)
@iuriandreazza
/iuri.andreazza
def resize(img, box, fit, out, quality, center,
ext="JPEG", save = True):
#...
def processRequest(file_path, w, h, fit, center, env_rec):
if not os.path.exists("/tmp/
images/"+file_original_path_s3):

res = k_file_original.get_contents_to_filename("/tmp/
images/"+file_original_path_s3)



im = Image.open("/tmp/images/"+file_original_path_s3)

im = resize(im, box, fit, "/tmp/images/files/"+env_rec
+"/"+file_rec_name, 100, center)

# ext = imghdr.what("/tmp/images/files/"+file_rec_name)

s3_utils.s3Push(bucket, file_path_s3, "/tmp/images/
files/"+env_rec+"/"+file_rec_name).start()



output = io.BytesIO()

im.save(output, format='JPEG') # or another format

output.seek(0)



return send_file(output, mimetype='image/JPEG')
app.py pense_lib.py
Stack-Py
@iuriandreazza
/iuri.andreazza
• Ex. deploy

PS: Colocar foto do MESOS e Marathon
Métricas (Stack-Py)
segundos
0
0,175
0,35
0,525
0,7
RPM
500 1000 4000 9000 20000
Tempo de Resp. IO/W
Mb
0
7,5
15
22,5
30
RPM
500 1000 4000 9000 20000
MEM
@iuriandreazza
/iuri.andreazza
Perguntas???
@iuriandreazza
/iuri.andreazza

Internet sem drama

  • 1.
    Internet sem Drama Enfrentandodesafios diários! @iuriandreazza /iuri.andreazza
  • 3.
    @iuriandreazza - Travel Engineering@ Fabuloso Destino - B.el em Ciência da Computação (Unisinos) - Engenheiro de Software/Devops - PHP,Python,Ruby,Java - RBS/Zap Imóveis - Geek - Tech Crazy - Early Adopter
  • 6.
    Do começo • Background •Deploy de 3 em 3 meses • Features requests semanais • 5 camadas de processos para deploy • Go live não agile • O que fazer? @iuriandreazza /iuri.andreazza
  • 7.
    Estrutura que havia •Deploy somente com script (GMud) • Sem acesso a PRD (mesmo sem nível de usuário ou logs) • Scripts de banco somente executados por um DB oficial • Somente atualizações não criticas durante o dia • Qualquer mudança de médio ou grande porte deveria ser a noite. @iuriandreazza /iuri.andreazza
  • 8.
    O que erarealmente bom? • Apoio dos DBAs • Apoio da Infra em questões estruturais • A necessidade de pensar bem antes de “Go Live” • Ambientes bem estáveis @iuriandreazza /iuri.andreazza
  • 10.
    O que eraruim? • Dificuldade de liberar rapidamente uma versão do portal • Resistência da equipe de infra-estrutura em aplicar patchs e correções • Grande dificuldade de se colocar algo rapidamente no ar. @iuriandreazza /iuri.andreazza
  • 12.
    O que enfrentávamos? •Necessidade de ajustar o negócio de forma rápida • Necessidade de colocar rapidamente soluções novas ou correções imediatas • Desenvolvimento era todo Agile, infra não era • Falta de processo e entendimento de como liberar o software do portal @iuriandreazza /iuri.andreazza
  • 14.
    PaaS/Cloud o que????? •Analise: • Ir para AWS - Amazon • Ajustar Infra do datacenter local e tentar fazer o melhor possível • Pesquisar e implementar um processo de deploy mais consigo e mais rápido com a infra • Começar a instigar soluções PaaS para a equipe, como openstack, mesos ou openshift. @iuriandreazza /iuri.andreazza
  • 15.
    Gestão de versão •Entender como separar features • Entender como quebrar em etapas entregáveis • Criar metodologia no time e na infra-estrutura de como liberar • Deploy-continuo consiste: • Desenvolvimento com Testes (TDD, BDD) • Facilidade de liberar uma versão nova sem downtime, ou com processo preciso. @iuriandreazza /iuri.andreazza
  • 16.
  • 17.
    Infra 1.5 • Ajustarcom a equipe de infra-estrutura para um deploy mais rápido • Processo de Deploy maquina-a-maquina • Scripts de banco que sejam incrementais e nunca quebrem o software • Liberação de regras para atualização de arquivos estáticos @iuriandreazza /iuri.andreazza
  • 18.
    Infra 2.0 • Moverpara a Amazon-AWS • Assumir toda a gestão da infra • Criar estrutura de deploy continuo usando Jenkins-CI • Adicionar e remover maquinas on-the-fly conforme a necessidade • Monitoramento avançado para uso do portal @iuriandreazza /iuri.andreazza
  • 19.
    Penseimoves->ZAP • Venda dopenseimoveis para o ZAP • 40 Milhões • Ocorreu somente por causa do movimento para o Cloud e da capacidade da equipe • ZAP absorveu a tecnologia e a equipe e trocou o portao penseimoveis pelo deles. @iuriandreazza /iuri.andreazza
  • 20.
    Recortando Imagens on-the-go •Problema: • Imagens do portal do antigo penseimoveis.com.br estavam estranhas • Debug: • As vezes os recortes eram entregues as vezes não • As vezes as imagens vinham parcialmente criadas • As vezes as imagens vinham coloridas e com “filtros" errados @iuriandreazza /iuri.andreazza
  • 21.
    Achando o problema! •Possíveis causas iniciais: • Tempo de resposta durante a entrega • Cache não sendo feito de forma correta (lado server) • Headers de cache não sendo colocados • Rede (3g/4g/Wifi/Ethernet …) • Recortador "baleando" @iuriandreazza /iuri.andreazza
  • 23.
    Estrutura que havia •Recortador dividia recursos com a aplicação principal • Tech-Stack: JAVA App + Glassfish Clusterizado 4.1 (App Server), varnish(webcache),apache(lb) • Datacenter RBS (4 Maquinas 32Gb) • 8Cores 2.3Ghz (Blades) • NAS - HDD SCSI/SSD • Link dedicado @iuriandreazza /iuri.andreazza
  • 24.
    Métricas (Stack-Java) segundos 0 0,75 1,5 2,25 3 RPM 500 10004000 9000 20000 Tempo de Resp. IO/W Mb 0 100 200 300 400 RPM 500 1000 4000 9000 20000 MEM @iuriandreazza /iuri.andreazza
  • 25.
    Desafios • Java-NIO • Causavaproblemas de IO e drop da JVM em alguns casos de concorrência • IO Wait (FS, NAS vs MemFS) • Espaço vs Escalabilidade vs Nível Cache • Hang Glassfish • Refatoring constante do codigo em busca de melhorias @iuriandreazza /iuri.andreazza
  • 26.
    Pragmatico! • Qual techusar? • Python? • comunidade bastante ativa • boa lib de manipulação de imagens “Pylon" • bom micro-framework web (@flask) • Simples de usar, pouco código necessário para fazer o mesmo • Simples de fazer deploy @iuriandreazza /iuri.andreazza
  • 27.
    Stack-Py • Usando Pyhton •PIL • flask • Setup (infra-estrutura) • Varnish • Nginx+ • 4 instancias flask @iuriandreazza /iuri.andreazza
  • 28.
    Stack-Py import sys
 import pense_lib
 fromflask import Flask
 from flask import request
 
 import hmac
 import hashlib
 import requests
 import base64
 import time
 import datetime
 
 app = Flask(__name__)
 app.config.from_pyfile('flaskapp.cfg')
 @app.route('/images/<path:file_path>')
 def static_asset(file_path): w = request.args.get('w', None)
 h = request.args.get('h', None)
 fit = request.args.get('fit', "f")
 env_rec = request.args.get('e', "production")
 #tratando de recorte
 center = request.args.get('c', "a")
 if "," in center:
 center = center.split(",")
 
 return pense_lib.processRequest(file_path, w, h, fit, center, env_rec) @iuriandreazza /iuri.andreazza def resize(img, box, fit, out, quality, center, ext="JPEG", save = True): #... def processRequest(file_path, w, h, fit, center, env_rec): if not os.path.exists("/tmp/ images/"+file_original_path_s3):
 res = k_file_original.get_contents_to_filename("/tmp/ images/"+file_original_path_s3)
 
 im = Image.open("/tmp/images/"+file_original_path_s3)
 im = resize(im, box, fit, "/tmp/images/files/"+env_rec +"/"+file_rec_name, 100, center)
 # ext = imghdr.what("/tmp/images/files/"+file_rec_name)
 s3_utils.s3Push(bucket, file_path_s3, "/tmp/images/ files/"+env_rec+"/"+file_rec_name).start()
 
 output = io.BytesIO()
 im.save(output, format='JPEG') # or another format
 output.seek(0)
 
 return send_file(output, mimetype='image/JPEG') app.py pense_lib.py
  • 29.
  • 30.
    Métricas (Stack-Py) segundos 0 0,175 0,35 0,525 0,7 RPM 500 10004000 9000 20000 Tempo de Resp. IO/W Mb 0 7,5 15 22,5 30 RPM 500 1000 4000 9000 20000 MEM @iuriandreazza /iuri.andreazza
  • 31.