Walled Garden
Redu
Apresentações
Guilherme Cavalcanti
github.com/guiocavalcanti
Tiago Ferreira
github.com/fltiago
Plataforma de educação a
distância construída em uma
estrutura de rede social
redu.com.br
Walled Garden
Monolítica Serviços
Redu
Analytics
Core
App Store
Serviços
• Resposabilidades bem
definidas
• API REST
• Privados
• On going process
• “Desmembrar”
serviços
Analytics
Core
...
Vantagens
• Evolução indepentente
• Liberdade de
tecnologia
• Menos overhead de
comunicação entre
pessoas
Analytics
Core
A...
CoreVis Apps
Walled Garden
Untied
github.com/redu/untied
Acoplamento entre serviços
• Comunicação “um para muitos”
• Identidade de serviços
Acoplamento entre serviços
Core
Vis
Apps
N
...
spaghetti
Service
Disponibilidade e tolerância
• Como lidar com não disponibilidade do
serviço?
• Estratégia de retry no cliente
• Em casos ...
Disponibilidade e tolerância
Core
Vis
N
...
x
Message Bus
Ideia
• Canal de comunicação transversal entre
todos os serviços
• Propagação de representações do domain
model (RESTishy)
The real
Walled Garden
CoreVis Apps
Message Bus
Messaging that just works
Upsides
• Tolerância a falhas (dos consumers)
• O trabalho do publisher termina ao enviar
a mensagem para o exchanger
• Ga...
Untied Publisher
github.com/redu/untied
Doorkeeper
class	
  DoorkeeperWithRepresenter
	
  	
  include	
  Untied::Doorkeeper
	
  	
  def	
  initialize
	
  	
  	
  ...
Features
• ActiveRecord lifecycle
• Propaga representações, não domain
models
• Multiplos adapters (Bunny & AMQP)
Untied Consumer
github.com/redu/untied
Observer
class	
  Builder	
  <	
  Untied::Consumer::Observer
	
  	
  observe	
  :user,	
  from:	
  "social-­‐network"
	
  ...
“Daemonizable”
$	
  ruby	
  consumerd.rb	
  start
$	
  ruby	
  consumerd.rb	
  status
untiedc:	
  running	
  [pid	
  52324...
Untied Plugins
github.com/redu/untied-consumer-sync
Padrões comuns
• Untied Consumer Sync
• Abstraí o padrão de replicar entidades
através de vários serviços
Como?
Untied::Consumer::Sync.configure	
  do	
  |config|
	
  	
  config.model_data	
  =	
  "mappings.yml"
end
User:	
  #	
...
Vis
Objetivos
• Garantia de entrega
• Assíncrono e escalável
• Fail-safe
• Independente de Framework
Big Picture
Core Vis
mongoDB
HTTP
Solução
• MongoDB
• Dados não estruturados
• Possibilidade de guardar estrutura de
dados complexas
• Mais facilmente escal...
Solução
• Aplicação isolada (fail-safe)
• Interação através de uma API REST
• em-http-request (requisições
assíncronas e p...
Implementação inicial
• Cliente da API (VisClient) bem simples
• Uso do em-http-request para envio de
requisições de forma...
Requisições
• Assíncronas
• Logs em arquivos
def	
  send_async_info(params,	
  url)
	
  	
  if	
  EM.reactor_running?
	
  ...
Requisições
• Paralelas
• Logs em arquivos
def	
  send_multi_request
	
  	
  ...
	
  	
  em	
  do
	
  	
  	
  	
  multi	
 ...
Parâmetros
• Preenchidos
manualmente
• Acesso a múltiplos
modelos
def	
  fill_enroll_params(enrollment_id,	
  type)
	
  	
...
Lições aprendidas
Lições Aprendidas
• Não havia interface única para envio das
notificações, ou seja, código espalhado e
de difícil manutenç...
Lições Aprendidas
• Lidar com requisições paralelas é difícil
• Pouco workers do nginx para muitas
requisições paralelas
•...
Atualmente
Atualmente
• Delayed Job lida com falhas e reenvios de
uma forma atômica
• VisClient responsável por criar Jobs e
construi...
New vis client
• Envio de requisições
(Faraday)
• Lógica de criação de
jobs
• Lógica de
parametrização
def	
  self.notify_...
Representer
module	
  Vis
	
  	
  module	
  EnrollmentVisRepresenter
	
  	
  	
  	
  include	
  Roar::Representer::JSON
	
...
Futuropróximo
Futuro
• Vis vai se tornar provedora de Relatórios e
Visualizações
• não haverá API de consulta
• relatórios e visualizaçõ...
Referências
• https://github.com/redu/permit
• https://github.com/redu/untied
• https://github.com/redu/untied-
consumer-s...
Redu walled garden
Upcoming SlideShare
Loading in …5
×

Redu walled garden

239 views
178 views

Published on

Apresentará as motivações e lições aprendidas na criação de uma aplicação de larga escala orientada a serviços. Entenda como fatores como performance, estilos de comunicação e produtividade da equipe relacionam-se à estruturação de uma aplicação.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
239
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
1
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Redu walled garden

  1. 1. Walled Garden Redu
  2. 2. Apresentações
  3. 3. Guilherme Cavalcanti github.com/guiocavalcanti Tiago Ferreira github.com/fltiago
  4. 4. Plataforma de educação a distância construída em uma estrutura de rede social redu.com.br
  5. 5. Walled Garden
  6. 6. Monolítica Serviços Redu Analytics Core App Store
  7. 7. Serviços • Resposabilidades bem definidas • API REST • Privados • On going process • “Desmembrar” serviços Analytics Core App Store
  8. 8. Vantagens • Evolução indepentente • Liberdade de tecnologia • Menos overhead de comunicação entre pessoas Analytics Core App Store
  9. 9. CoreVis Apps Walled Garden
  10. 10. Untied github.com/redu/untied
  11. 11. Acoplamento entre serviços • Comunicação “um para muitos” • Identidade de serviços
  12. 12. Acoplamento entre serviços Core Vis Apps N ...
  13. 13. spaghetti Service
  14. 14. Disponibilidade e tolerância • Como lidar com não disponibilidade do serviço? • Estratégia de retry no cliente • Em casos de falhas de HTTP
  15. 15. Disponibilidade e tolerância Core Vis N ... x
  16. 16. Message Bus
  17. 17. Ideia • Canal de comunicação transversal entre todos os serviços • Propagação de representações do domain model (RESTishy)
  18. 18. The real Walled Garden CoreVis Apps Message Bus
  19. 19. Messaging that just works
  20. 20. Upsides • Tolerância a falhas (dos consumers) • O trabalho do publisher termina ao enviar a mensagem para o exchanger • Garantia de entrega
  21. 21. Untied Publisher github.com/redu/untied
  22. 22. Doorkeeper class  DoorkeeperWithRepresenter    include  Untied::Doorkeeper    def  initialize        watch  User,  :after_create,  represent_with:  UserRepresenter        watch  Course,  :after_create,  represent_with:  CourseRepresenter    end end
  23. 23. Features • ActiveRecord lifecycle • Propaga representações, não domain models • Multiplos adapters (Bunny & AMQP)
  24. 24. Untied Consumer github.com/redu/untied
  25. 25. Observer class  Builder  <  Untied::Consumer::Observer    observe  :user,  from:  "social-­‐network"      def  build(attrs)        LeanUser.new(attrs)    end    alias_method  :after_create,  :build end • Lifecycle • Configuração • Framework agnostic
  26. 26. “Daemonizable” $  ruby  consumerd.rb  start $  ruby  consumerd.rb  status untiedc:  running  [pid  52324] $  ruby  consumerd.rb  stop untiedc:  trying  to  stop  process  with  pid  52324.. untiedc:  process  with  pid  52324  successfully  sto worker  =  Untied::Consumer::Worker.new worker.daemonize(pids_dir:  pids_dir,  log_dir:   • gem “deamons” • Monit, god, etc
  27. 27. Untied Plugins github.com/redu/untied-consumer-sync
  28. 28. Padrões comuns • Untied Consumer Sync • Abstraí o padrão de replicar entidades através de vários serviços
  29. 29. Como? Untied::Consumer::Sync.configure  do  |config|    config.model_data  =  "mappings.yml" end User:  #  Payload's  type    attributes:  #  Needed  attributes        -­‐  id        -­‐  login        -­‐  first_name        -­‐  last_name    mappings:        id:  core_id  #  Maps  payload's  id  key  to  model'    name:  LeanUser  #  Model  name • Configuração • Definição de atributos • Definição de mapeamentos • ActiveRecord • Mongoid
  30. 30. Vis
  31. 31. Objetivos • Garantia de entrega • Assíncrono e escalável • Fail-safe • Independente de Framework
  32. 32. Big Picture Core Vis mongoDB HTTP
  33. 33. Solução • MongoDB • Dados não estruturados • Possibilidade de guardar estrutura de dados complexas • Mais facilmente escalável • Boa biblioteca de consulta
  34. 34. Solução • Aplicação isolada (fail-safe) • Interação através de uma API REST • em-http-request (requisições assíncronas e paralelas)
  35. 35. Implementação inicial • Cliente da API (VisClient) bem simples • Uso do em-http-request para envio de requisições de forma assíncrona e paralela • Falhas logadas em arquivos • Uso extensivo de Observers
  36. 36. Requisições • Assíncronas • Logs em arquivos def  send_async_info(params,  url)    if  EM.reactor_running?        do_request(params,  url,  true)    else        ...    end end   def  do_request(params,  url,  self_reactor)    http  =  EM::HttpRequest.new(url).post({:body  =>  params.to_json  })      http.callback  do        ...        rescue              log.error  "log  goes  here..."        end        EM.stop  unless  self_reactor    end      http.errback    do        ...        rescue            log.error  "log  goes  here..."        end        EM.stop  unless  self_reactor    end end
  37. 37. Requisições • Paralelas • Logs em arquivos def  send_multi_request    ...    em  do        multi  =  EventMachine::MultiRequest.new                enrollments.each_with_index  do  |enroll,  idx|            multi.add  idx,  EM::HttpRequest.new(url).post({                :body  =>  enroll.to_json  })        end          multi.callback  do            multi.responses[:errback].each  do  |err|                logger.error  "logs  goes  here..."            end              EM.stop  unless  @running        end    end end
  38. 38. Parâmetros • Preenchidos manualmente • Acesso a múltiplos modelos def  fill_enroll_params(enrollment_id,  type)    ...    if  enrollment        course  =  enrollment.subject.space.course        params  =  {            :user_id  =>  enrollment.user_id,            :type  =>  type,            :lecture_id  =>  nil,            :subject_id  =>  enrollment.subject_id,            :space_id  =>  enrollment.subject.space.id,            :course_id  =>  course.id,            ...            :created_at  =>  enrollment.created_at,            :updated_at  =>  enrollment.updated_at        }    else        nil    end end
  39. 39. Lições aprendidas
  40. 40. Lições Aprendidas • Não havia interface única para envio das notificações, ou seja, código espalhado e de difícil manutenção • O em-http-request é construído em cima do EventMachine • Logar em arquivos com propósito de recuperar falhas é uma bola de neve
  41. 41. Lições Aprendidas • Lidar com requisições paralelas é difícil • Pouco workers do nginx para muitas requisições paralelas • Difícil depuração
  42. 42. Atualmente
  43. 43. Atualmente • Delayed Job lida com falhas e reenvios de uma forma atômica • VisClient responsável por criar Jobs e construir os parâmetros • Simples depuração e detecção de falhas • Uso de representers github.com/apotonick/roar
  44. 44. New vis client • Envio de requisições (Faraday) • Lógica de criação de jobs • Lógica de parametrização def  self.notify_delayed(resource,  type,  args)    elements  =  args.respond_to?(:map)  ?  args  :  [args]    notifier_builder  =  NotifierBuilder.new(resource,                                            type,  elements)    notifier_builder.build end
  45. 45. Representer module  Vis    module  EnrollmentVisRepresenter        include  Roar::Representer::JSON          property  :user_id        property  :subject_id        property  :space_id        property  :course_id        property  :created_at        property  :updated_at          def  space_id            self.subject.space.id        end          def  course_id            self.subject.space.course.id        end    end end
  46. 46. Futuropróximo
  47. 47. Futuro • Vis vai se tornar provedora de Relatórios e Visualizações • não haverá API de consulta • relatórios e visualizações estarão em Vis, front-end incluso • inclusão será feita através de iframe
  48. 48. Referências • https://github.com/redu/permit • https://github.com/redu/untied • https://github.com/redu/untied- consumer-sync

×