3. ¿Cuál es el costo de una falla?
• Una pequeña molestia para algún usuario.
!
• Una transacción (de negocio) no completada.
• Datos inconsistentes.
!
• No disponibilidad del sistema. O_o
!
• Pérdida de un cliente.
• O de muchos de ellos.
!
• Muerte de una organización.
5. Las falacias de los sistemas distribuidos
1. La red es confiable.
2. La latencia es cero.
3. El ancho de banda es infinito.
4. La red es segura.
5. La topología no cambia.
6. Existe solo un administrador.
7. El costo del transporte es cero.
8. La red es homogénea.
9. 1. Aceptar: No puedes prevenir todas las fallas.
2. Evita los “puntos únicos de falla”.
3. Implementa mecanismos de detección de
errores.
4. Implementa corrección de errores.
• Si es posible y hace sentido.
• e.g. patrón: Compensating Transactions ?
5. Contención de errores
1. Evita que se propaguen.
10. Consecuencias
Sistemas…
• Creados de componentes pequeños,
independientes en tiempo de ejecución.
• Distribuidos.
• Con reintentos finitos.
• Con respuestas apropiadas para casos de
falla.
15. Timeouts (1)
// Básico 1
myObject.wait(); // No uses esto por default
myObject.wait(TIMEOUT); // Mejor usa esto
!
// Básico 2
myThread.join(); // No uses esto por default
myThread.join(TIMEOUT); // Mejor usa esto
16. Timeouts (2)
// Utilizando el API de concurrencia de Java
<MyActionResult> myAction = <My Blocking Action>
ExecutorService executor =
Executors.newSingleThreadExecutor();
Future<MyActionResult> future = executor.submit(myAction);
MyActionResult result = null;
try {
result = future.get(); // No uses esto por default
result = future.get(TIMEOUT, TIMEUNIT); // Mejor usa esto
} catch (TimeoutException e) { // Si ocurre el timeout
...
} catch (...) {
...
}
17. Timeouts (3)
// Utilizando el SimpleTimeLimiter de Guava
Callable<MyActionResult> myAction = <My Blocking Action>
SimpleTimeLimiter limiter = new SimpleTimeLimiter();
MyActionResult result = null;
try {
result = limiter.callWithTimeout(myAction,
TIMEOUT, TIMEUNIT, false);
} catch (UncheckedTimeoutException e) {
...
} catch (...) {
... }
21. Circuit Breaker (3)
public class CircuitBreaker implements MyResource {
public enum State { CLOSED, OPEN, HALF_OPEN }
final MyResource resource;
State state;
int counter;
long tripTime;
public CircuitBreaker(MyResource r) {
resource = r;
state = CLOSED;
counter = 0;
tripTime = 0L;
} ...
22. Circuit Breaker (4)
...
public Result access(...) { // resource access
Result r = null;
if (state == OPEN) {
checkTimeout();
throw new ResourceUnavailableException();
}
try {
r = resource.access(...); // should use timeout
} catch (Exception e) {
fail();
throw e;
}
success();
return r;
}
...
28. Fail Fast (3)
public class FailFastGuard {
private FailFastGuard() {}
public static void checkResources(Set<CircuitBreaker> resources) {
for (CircuitBreaker r : resources) {
if (r.getState() != CircuitBreaker.CLOSED) {
throw new ResourceUnavailableException(r);
}
}
}
}
29. Fail Fast (4)
public class MyService {
Set<CircuitBreaker> requiredResources;
// Initialize resources
...
public Result myExpensiveAction(...)
{
FailFastGuard.checkResources(requiredResources);
// Execute core action
...
}
}
33. Shed Load (3)
public class ShedLoadFilter implements Filter {
Random random;
public void init(FilterConfig fc) throws ServletException {
random = new Random(System.currentTimeMillis());
}
public void destroy() {
random = null;
} ...
34. Shed Load (4)
...
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws java.io.IOException, ServletException {
int load = getLoad();
if (shouldShed(load)) {
HttpServletResponse res = (HttpServletResponse)response;
res.setIntHeader("Retry-After", RECOMMENDATION);
res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
chain.doFilter(request, response);
}
...