断路器设计模式

断路器是一个现代软体开发设计模式。用以侦测错误,并避免不断地触发相同的错误(如维护时服务不可用、暂时性的系统问题或是未知的系统错误)。

常用时机 编辑

假设有个应用程式每秒会与资料库沟通数百次,此时资料库突然发生了错误,程式设计师并不会希望在错误时还不断地访问资料库。因此会在等待TCP连线逾时之前直接处理这个错误,并进入正常的结束程序(而非直接结束程式)。简单来说,断路器会侦测错误并且“预防”应用程式不断地呼叫一个近乎毫无回应的服务(除非该服务已经安全到可重试连线了)。

概念 编辑

断路器有分简单与较进阶的版本,简单的断路器只需要知道服务是否可用。而较进阶的版本比起前者更有效率。进阶的断路器带有至少三个状态:

  • 关闭:断路器在预设的情形下是呈现关闭的状态,而断路器本身“带有”计数功能,每当错误发生一次,计数器也就会进行“累加”的动作,到了一定的错误发生次数断路器就会被“开启”,这个时候亦会在内部启用一个计时器,一旦时间到了就会切换成半开启的状态。
  • 开启:在开启的状态下任何请求都会“直接”被拒绝并且抛出异常讯息。
  • 半开启:在此状态下断路器会允许部分的请求,如果这些请求都能成功通过,那么就意味著错误已经不存在,则会被“切换回”关闭状态并“重置”计数。倘若请求中有“任一”的错误发生,则会回复到“开启”状态,并且重新计时,给予系统一段休息时间。

效能考量 编辑

当安全是个益处,效能也就成为了实作断路器的一个负面考量。因为需要不断地检查一个服务是否安全,且服务不仅会有一个,甚至会以多个方向扩展。

实作范例 编辑

PHP 编辑

下面是一个以 PHP 来实作的范例。这个范例是将一个 MySQL 伺服器的可用状态处存进共享记忆体快取(APC)中并在之后以此判断是否可用。

检查 编辑

下列脚本能以工作排程来不断地在某时刻执行检查。

$db = mysql_connect('localhost','user','pass');
if ($db === false) {
    apc_store('dbUp', '已斷線');
} else {
    apc_store('dbUp', '可連線');
    @mysql_close($db);
}

在应用程式中使用 编辑

if (apc_fetch('dbUp') === '已斷線') {
    echo "資料庫目前不可用。請在數分鐘後嘗試。";
    exit;
}
$db  = mysql_connect('localhost', 'user', 'pass');
$res = mysql_db_query('database', 'SELECT * FROM table');

外部链接 编辑