python断路器模式实现
circuitbreaker的Python项目详细描述
断路器
这是“断路器”模式(http://martinfowler.com/bliki/CircuitBreaker.html)的python实现。 灵感来自michael t.nygard高度推荐的书发行它!(https://pragprog.com/book/mnee/release-it)。
安装
该项目在pypi上可用。只需运行:
$ pip install circuitbreaker
用法
这是最简单的例子。只需使用@circuitdecorator装饰函数:
from circuitbreaker import circuit @circuit def external_call(): ...
此装饰器使用默认设置设置设置断路器。断路器:
- 监视函数执行并统计失败次数
- 每次成功执行(关闭时)后重置失败计数。
- 打开并防止在5次后续故障后执行进一步的操作
- 切换到半开状态,并允许在30秒恢复超时后执行一次测试
- 如果测试执行成功,则关闭
- 将所有引发的异常(基于类Exception)视为预期的失败
- 被命名为“external_call”-它修饰的函数的名称
失败是什么意思?
failure是引发的异常,在函数调用期间未捕获到该异常。 默认情况下,断路器侦听基于类Exception的所有异常。 这意味着,在函数调用期间引发的所有异常都被视为 “预期失败”并将增加失败计数。
明确预期故障
在定义预期异常时,尽可能具体地是很重要的。 断路器的主要用途是保护分布式系统不受级联故障的影响。 也就是说,你可能只想打开断路器,如果集成点在另一个 结束不可用。例如,如果有一个ConnectionError或一个请求Timeout。
如果您使用请求库(http://docs.python-requests.org/)进行http调用, 它的RequestException类对于expected_exception参数来说是一个很好的选择。
无论如何,所有已识别的异常都将被重新引发,但目标是,只让断路器 识别与集成点通信相关的异常。
当涉及到监控(参见Monitoring)时,如果 由于本地OSError或KeyError等原因,断路器断开。
配置
可以通过decorator参数调整以下配置选项。例如:
from circuitbreaker import circuit @circuit(failure_threshold=10, expected_exception=ConnectionError) def external_call(): ...
故障阈值
默认情况下,断路器在5次后续故障后打开。可以使用failure_threshold参数调整此值。
恢复超时
默认情况下,断路器保持打开30秒以允许集成点恢复。 可以使用recovery_timeout参数调整此值。
预期异常
默认情况下,断路器侦听基于Exception类的所有异常。 您可以使用expected_exception参数调整此值。它可以是异常类,也可以是异常类的元组。
姓名
默认情况下,断路器名称是它所修饰的函数的名称。您可以使用参数name调整名称。
高级用法
如果将断路器应用于几个功能,并且始终设置默认值以外的特定选项, 您可以扩展CircuitBreaker类并创建自己的断路器子类:
from circuitbreaker import CircuitBreaker class MyCircuitBreaker(CircuitBreaker): FAILURE_THRESHOLD = 10 RECOVERY_TIMEOUT = 60 EXPECTED_EXCEPTION = RequestException
现在,您有两个选项可以将断路器应用到函数。直接作为对象:
@MyCircuitBreaker() def external_call(): ...
请注意,断路器类必须初始化,您必须使用类实例作为decorator(@MyCircuitBreaker()),而不是类本身(@MyCircuitBreaker)。
或者通过decorator代理:
@circuit(cls=MyCircuitBreaker) def external_call(): ...
监控
为了跟踪应用程序的运行状况和断路器的状态,每个断路器都会在CircuitBreakerMonitor中注册自己。您可以通过CircuitBreakerMonitor.get_circuits()接收所有注册的断路器。
要获得聚合的运行状况状态,可以通过CircuitBreakerMonitor.all_closed()向监视器询问。或者您可以通过CircuitBreakerMonitor.get_open()检索当前打开的电路,通过CircuitBreakerMonitor.get_closed()检索关闭的电路。
待办事项
- 添加单元测试