一文让你彻底弄清failfast、failsafe、failover、failback、failsilent

背景

最近参与了部门的稳定性建设,时常会看到一些failxxxx的字眼,常见的场景如:在Java集合迭代过程中,如果集合有修改就会抛出一个ConcurrentModificationException异常,这就是一种典型的fail-fast机制。

经过查阅资料,原来这些专有名词都有一个统一的名字:容错机制。终于,借此机会对常见的容错机制进行一下总结,方便以后学习。

文章中若有本人理解或描述不当之处,欢迎老铁们指出~

fail-fast - 快速故障

在系统设计中,快速故障系统是一种可以立即报告任何可能表明故障的情况的系统。快速故障系统通常旨在停止正常操作,而不是继续尝试可能有问题的过程。此类设计通常会在操作中的多个点检查系统状态,因此可以及早发现故障。快速故障模块的职责是检测错误,然后让系统优先处理。

private SystemService systemService;

public String failFast() {
	boolean result = systemService.executeFailFastTask();
	if (result) {
		return "success";
	} else {
		throw new RuntimeException("执行失败"); // fail-fast
	}
}
  • Example : List集合中迭代器的next()方法,只要检测到正在遍历的集合对象进行了修改,就会立即抛出并发修改异常(ConcurrentModificationException)
public E next() {
	checkForComodification();
	// 省略下面的代码
}
final void checkForComodification() {
	if (modCount != expectedModCount)
			throw new ConcurrentModificationException();
}
  • 总结如果系统出现故障,就立即中止系统并抛出故障

fail-safe - 故障安全

如果系统出现特定类型的故障(不会对系统造成伤害或影响非常小的故障),则可以忽略,因为此类故障不会造成损失或损失在可接受范围内。故障安全机制可以保证系统在故障前和故障后保持一样的安全状态。

private SystemService systemService;

public String failSafe() {
    boolean result = systemService.executeFailSafeTask();
    if (result) {
        return "success";
    } else {
        return "failed"; // fail-safe
    }
}
  • Example : CopyOnWriteArrayList在迭代器的实现上没有抛出 ConcurrentModificationException,从而避免了fail-fast。CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
public E next() {
    if (!hasNext())
        throw new NoSuchElementException();
    return (E) snapshot[cursor++];
}

public boolean hasNext() {
    return cursor < snapshot.length;
}
  • 总结如果系统出现故障,则进行忽略,以保证系统正常运行

fail-over - 故障转移

故障转移是系统出现故障或异常终止时切换到冗余或备用的系统。故障转移通常是系统自动进行的并且往往在没有告警的情况下运行,不需要人工干预。

private SystemService systemService;
private SystemService backupSystemService;

private static boolean defaultSet = Boolean.TRUE;

public String failOver() {
    if (defaultSet) {
        try {
            systemService.executeFailOverTask();
        } catch (Exception e) {
            //fail-over: 调用主要外部服务发生故障,则切换为备用外部服务
            defaultSet = Boolean.FALSE;
            backupSystemService.executeFailOverTask();
        }
    } else {
        backupSystemService.executeFailOverTask();
    }
    return "success";
}
  • Example : MySQL的双Master模式,节点 A 和 B 之间总是互为主备关系,如果 A 实例出现故障,则切换至从 B 实例。
    file

  • 总结如果系统出现故障,则切换到备用系统

fail-back - 故障恢复

故障恢复是指将之前处于故障状态的系统恢复到原始工作状态,主系统可用后,自动从备用系统恢复到主系统。

private static boolean needSwitchToMaster = Boolean.FALSE;

public void failBack() {
    while (true) {
        if (masterSystemAvailable()) {
            //fail-back
            needSwitchToMaster = Boolean.TRUE;
            break;
        }
    }
}
  • Example : MySQL的双Master模式,节点 A 和 B 之间总是互为主备关系,如果 A 实例出现故障,则切换至从 B 实例。
    file
  • 总结failover之后的自动恢复过程,切换回可用的主系统

fail-silent - 故障沉默

故障沉默:调用服务失败后,就默认该服务一定时间内无法再对外提供服务,不再向它分配请求流量,将错误隔离开来,避免对其他服务产生影响。

private static long downDuration = 0L;

/**
 * 省略 downDuration 的计算过程
 */
public String failSilent() {
    if (downDuration <= 0L) {
        boolean result = systemService.executeFailSilentTask();
        if (result) {
            return "success";
        }
        downDuration = initDownDuration();
        return "failed";
    } else {
        return backupSystemService.executeFailSilentTask() ? "success" : "failed";
    }
}
  • Example : 经常超时的服务可以使用faile-silent容错机制,防止请求堆积而消耗大量的线程、内存、网络等资源,进而影响到整个系统的稳定。
    file
  • 总结将不可用服务进行隔离一段时间,避免影响整个系统的稳定性

总结

file

参考

  • https://blog.csdn.net/u011305680/article/details/79730646
  • http://icyfenix.cn/distribution/traffic-management/failure.html

本文仅介绍了几种常见的容错机制,欢迎老铁们进行讨论和补充~

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值