Disyuntores: o cómo no terminar viviendo abajo de un puente
En esta charla para ruby.conf.online repasamos rápidamente el patrón Circuit Breaker, sus usos, ventajas y desventajas, y cómo aprovecharlo utilizando la gema disyuntor.
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
# 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
• 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.
tied up in operations which are likely to fail. You avoid waiting on timeouts for the client, and a broken circuit avoids putting load on a struggling server.”
try(&block) half_open! if timed_out? ! case when closed? then circuit_closed(&block) when half_open? then circuit_half_open(&block) when open? then circuit_open end end ! def circuit_closed(&block) ret = block.call rescue open! if increment_failures! > threshold raise else
! disyuntor = Disyuntor.new(threshold: 1, timeout: 60) ! disyuntor.on_circuit_open { "" } ! Benchmark.ips do |r| r.report("sin") do begin Redis.current.ping rescue Redis::BaseError "" end end ! r.report("con") do begin disyuntor.try { Redis.current.ping } rescue Redis::BaseError "" end end ! r.compare! end
Martin Fowler: Circuit Breaker http://goo.gl/7Nmy6A • Making the Netflix API More Resilient http://goo.gl/VLO9Sq • Gemas github.com/inkel/disyuntor github.com/wsargent/circuit_breaker • Esta presentación https://goo.gl/B2YbBA