对软件系统来说,调用一个跑在不同进程里,或者不同机器上的服务非常普遍。远程调用和本地调用一个最大的区别就是远程调用会失败,或者直到超时才会有响应。如果你有很多这种服务提供者就会更糟糕,它们会耗尽主要资源,导致多个系统的层级错误。于是提出了断路器模式来避免这种灾难性错误。
断路器的基本理念很简单。将受保护的方法调用包装到断路器对象中,它会监控调用失败。一旦失败动用次数达到一个指定的阈值,断路器会打开(the circuit breaker trips),后续的对断路器的所有调用会直接失败,并不会调用保护的方法。通常在断路器打开时需要有某种方式的通知。
当断路器打开时,断路器不会对受保护方法进行调用,但调用可用时,需要重置断路器。这在建筑中的电路断路器是可行的,但在软件断路器中,我们可以让断路器自己检测是否调用可用。可以通过在一段恰当的时间后对受保护的方法再次进行调用,当调用成功后重置断路器状态。 半开状态意味着断路器准备进行真实调用来检测问题是否修复。如果调用成功,则重置断路器。如果失败则重新设置超时。
实际中,断路器提供来很多的特性和参数。通常它们会防治被保护的方法抛出错误,比如网络连接失败。不是所有的错误都能触发断路器,一些错误是反映正常的失败,需要作为正常逻辑的一部分来处理。
当网络流量大时,等待很多调用的超时会出问题。因为远端调用通常很慢,一般会将不同调用放在不同的线程中,通过future或promise处理返回的结果。通过在断路器中使用线程池,当断路器中的线程池耗尽时,你可以让断路器打开。
断路器可以降低资源在可能失败的操作中的绑定。客户端避免来超时等待,打开的断路器避免了将负载放在慢的服务器上。在这里说的远程调用通常是断路器的一个通用的例子,但断路器也可以在其它情况下使用,比如可以将系统希望保护的部分与其它部分隔离开
断路器是监控的好地方。任何断路器状态的改变都应当被打印日志,断路器应当展示状态的详细信息用于深度监控。在生产环境中,断路器行为通常是更深问题的很好的警告来源。操作员应当能够打开或重置断路器。
断路器本身是有价值的,但使用的客户端需要对断路器失败有响应。对于远程调用来说,你需要考虑失败后该做什么。正在执行的操作是否失败?有没有什么变通的方法?信用卡鉴权可能会被放在一个队列中等待后续处理,获取数据失败则可以展示错误的数据。
参考: