Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Disyuntores - Ruby Meetup Agosto 2016

Leandro López
August 11, 2016
39

Disyuntores - Ruby Meetup Agosto 2016

Leandro López

August 11, 2016
Tweet

Transcript

  1. Disyuntores O cómo no terminar viviendo abajo de un puente

  2. {github,twitter}.com/inkel Web Developer DevOps Wannabe Citrusbyte RubyConfAR No sé diseñar

    slides Fundamentalista de la barba Lector
  3. goodreads.com/inkel

  4. None
  5. • Aplicaciones distribuidas • SOA • Microservicios

  6. twitter.com/adrianco

  7. None
  8. on get, "pokemon" do render("pokemon/index", pokemons: PokeDex.all) end

  9. None
  10. None
  11. Ser popular tiene su precio 1. Más visitas 2. Más

    consultas a la base de datos 3. Más lenta cada consulta 4. Mayor cantidad de recursos 5. Timeouts 6. GOTO 2
  12. None
  13. on get, "pokemon" do pokemons = Cache.fetch(:pokemons) do PokeDex.all end

    render("pokemon/index", pokemons:pokemons) end
  14. on get, "pokemon" do pokemons = Cache.fetch(:pokemons) do PokeDex.all end

    render("pokemon/index", pokemons:pokemons) end
  15. Creemos que las cosas fallan así...

  16. ...cuando en realidad fallan así

  17. “Si algo puede salir mal, probablemente salga mal” Edward A.

    Murphy Jr.
  18. Cosas que pueden fallar • Cache • Base de datos

    • Saturación de red • Particiones de red • Noisy-neighbor • CPU • OOM • Espacio libre • Timeouts • Índices viejos • Integer overflow • Etcétera
  19. None
  20. es.wikipedia.org/wiki/Disyuntor Un disyuntor, interruptor automático (España), automático (Chile), breaker o

    pastilla (México) o taco (Colombia), es un aparato capaz de interrumpir o abrir un circuito eléctrico cuando la intensidad de la corriente eléctrica que por él circula excede de un determinado valor, o en el que se ha producido un cortocircuito, con el objetivo de evitar daños a los equipos eléctricos. A diferencia de los fusibles, que deben ser reemplazados tras un único uso, el disyuntor puede ser rearmado una vez localizado y reparado el problema que haya causado su disparo o desactivación automática.
  21. es.wikipedia.org/wiki/Disyuntor Un disyuntor, interruptor automático (España), automático (Chile), breaker o

    pastilla (México) o taco (Colombia), es un aparato capaz de interrumpir o abrir un circuito eléctrico cuando la intensidad de la corriente eléctrica que por él circula excede de un determinado valor, o en el que se ha producido un cortocircuito, con el objetivo de evitar daños a los equipos eléctricos. A diferencia de los fusibles, que deben ser reemplazados tras un único uso, el disyuntor puede ser rearmado una vez localizado y reparado el problema que haya causado su disparo o desactivación automática.
  22. Circuit Breaker Pattern • Controla el acceso y ejecución de

    un bloque de código • Sobrepasado el límite de errores consecutivos, abre el circuito • Todo intento a ejecutar el código falla con un error conocido • Pasado cierto timeout, intenta ejecutar el código • Si funciona correctamente, cierra el circuito • Si falla, comienza el ciclo nuevamente
  23. None
  24. Ejemplo

  25. # A partir del décimo error consecutivo, abrir el circuito

    # y esperar 5 segundos para volver a intentarlo. disyuntor_cache = Disyuntor.new(threshold: 10, timeout: 5) # A partir del quinto error consecutivo, abrir el circuito # y esperar 1 minuto para volver a intentarlo. disyuntor_db = Disyuntor.new(threshold: 5, timeout: 60) # Ejecutar una acción personalizada cuando el circuito esté # abierto. disyuntor_db.on_circuit_open do fail DBNotFound end
  26. on get, "pokemons" do begin pokemons = get_pokemons_from_cache render("pokemons/index", pokemons:

    pokemons) rescue DBNotFound render("db_not_found") end end
  27. on get, "pokemons" do begin pokemons = get_pokemons_from_cache render("pokemons/index", pokemons:

    pokemons) rescue DBNotFound render("db_not_found") end end
  28. def get_pokemons_from_cache disyuntor_cache.try do Cache.fetch(:pokemons) do get_pokemons end end rescue

    Disyuntor::CircuitOpenError get_pokemons end
  29. def get_pokemons_from_cache disyuntor_cache.try do Cache.fetch(:pokemons) do get_pokemons end end rescue

    Disyuntor::CircuitOpenError get_pokemons end
  30. def get_pokemons_from_cache disyuntor_cache.try do Cache.fetch(:pokemons) do get_pokemons end end rescue

    Disyuntor::CircuitOpenError get_pokemons end
  31. def get_pokemons disyuntor_db.try do PokeDex.all end end

  32. None
  33. Festejar con moderación resiliente 1. adj. Que tiene resiliencia. resiliencia

    Del ingl. resilience, y este der. del lat. resiliens, -entis, part. pres. act. de resilīre 'saltar hacia atrás, rebotar', 'replegarse'. 1. f. Capacidad de adaptación de un ser vivo frente a un agente perturbador o un estado o situación adversos. 2. f. Capacidad de un material, mecanismo o sistema para recuperar su estado inicial cuando ha cesado la perturbación a la que había estado sometido.
  34. Entonces, ¿qué conseguimos? • Si uno de los servicios no

    funciona falla inmediatamente. • Menor consumo de recursos en los servidores, debido a no ejecutar código que sabemos va a fallar. • Menos intervención manual dado que el sistema se “arregla” automáticamente. • Disminución en el número de errores en cascada.
  35. “A su manera, los disyuntores ayudan a reducir recursos asociados

    a operaciones que probablemente vayan a fallar. Evitás esperar un timeout en el cliente, y un circuito abierto evita poner carga en un servidor sobrecargado.” Martin Fowler
  36. Disyuntores en Ruby • github.com/wsargent/circuit_breaker • github.com/soundcloud/simple_circuit_breaker • github.com/pedro/cb2 •

    github.com/inkel/disyuntor • Implementalo vos!
  37. None
  38. Su consulta no molesta

  39. • Release It!: Design and Deploy Production-Ready Software • Martin

    Fowler: Circuit Breaker • Improved production stability with circuit breakers • Making the Netflix API More Resilient • Esta charla Más info