码迷,mamicode.com
首页 > 其他好文 > 详细

3分钟简述熔断器使用方法

时间:2020-11-12 14:28:57      阅读:19      评论:0      收藏:0      [点我收藏+]

标签:pytho   参考   expec   water   责任   ref   调用   传递   联系   

3分钟简述熔断器使用方法

收录于话题
#最近文章
5个
熔断器是一种设计模式,广泛用于分布式系统中,以防止级联故障。在这篇文章中,我们将通过级联故障的问题,来介绍熔断器模式的使用方法。

动机:级联故障的问题

在进入熔断器模式之前,让我们来看看它到底要解决什么问题。

当服务 A 尝试与服务 B 通信时,它会分配一个线程来进行该调用。在进行调用的时候,有 2 种故障可能发生,以 user 调用 friends 服务为例。

‘‘‘ user service ‘‘‘ 
def get_user_info(user_id: str):  
    try:    
        friends_service.get_friends(user_id)  
    except Exception as e:    
        raise InternalServerE
```rror

即时故障:在即时故障中,会立即引发一个异常(如:连接拒绝),并释放服务 A 线程。

超时故障:如果 service_b 需要很长的时间来响应,当收到服务 A 的新请求时,会有越来越多的线程在等待 service_b。如果在等待超时的过程中发出了多个请求,这就会耗尽服务 A 的线程池,会使服务 A 瘫痪。

> “您的代码不能永远等待一个不会返回的响应,迟早需要放弃等待,希望这不是一个设计方法。”-Michael T. Nygard,Release It!

下面通过一个社交媒体应用的例子来更好的解释这个问题。我们有一个聚合器服务,这是客户端交互的内容,它聚合了一堆服务的结果,包括 User 服务。User 服务调用 Photos 服务和 Friends 服务,而 Friends 服务又依赖 friends_db。
![](https://s4.51cto.com/images/blog/202011/01/ca959352968a8539c3880122ae559fc7.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

在这里,friends 服务试图向 friends_db 发出请求,但是,friends_db 并没有立即响应失败,而是让 friends 服务的线程一直在等待。Friends 服务尝试重试,从而使用更多线程。随着它收到新请求,更多线程正在等待 friends_db 返回结果。
![](https://s4.51cto.com/images/blog/202011/01/b4fdc3a479bd89dd27f3bdcd60a08bff.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

现在可以看到,Friends 服务现在如何成为 User 服务超时的来源。User 用尽了它的线程池来等待来自 Friends 服务的请求,就像 Friends 服务是如何等待 friends_db 一样。现在,我们可以看到 friends_db 中的故障是如何导致间接依赖于它的服务级联失败的。
![](https://s4.51cto.com/images/blog/202011/01/233421f76d19011d5f5e42149842b579.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

最终,聚合器服务也会由于相同的原因而崩溃。客户端调用了聚合服务,因此我们的系统实际也变得不可用。

我们看到架构的一个组件中的一个错误是如何导致级联故障,而导致所有其他服务崩溃。
![](https://s4.51cto.com/images/blog/202011/01/2da3450c6cbf6e510aa2e16cbfe52bb2.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

## 熔断器模式

熔断器通常以拦截器模式/责任链/过滤器的形式实现,它包含3个状态:

* 关闭:允许拦截器将所有请求传递给上游服务,并将上游服务的响应传递给调用方。
* 打开:不允许请求传递给上游,默认返回通常是错误响应。
* 半开放式:某些请求被允许传递到上游,其他请求被终止并返回默认响应。
![](https://s4.51cto.com/images/blog/202011/01/4bfa64a2ba48bcbd8eaf2487b7dd5c92.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

下图显示了处于三种状态的熔断器拦截器
![](https://s4.51cto.com/images/blog/202011/01/ce7ca4ec814e1a07dc7843b9b1966e2d.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

让我们看一下熔断器的 Python 示例,可以使用以下方法创建自己的熔断器:

from circuitbreaker import CircuitBreaker
class MyCircuitBreaker(CircuitBreaker):
FAILURE_THRESHOLD = 20
RECOVERY_TIMEOUT = 60
EXPECTED_EXCEPTION = RequestExceptionbr/>@MyCircuitBreaker()
def get_user_info(user_id):
try:
friends_service.get_friends(user_id)
except Exception as e:
raise InternalServerError


我们也可以利用 sidecar 模式。通过这种方法,不必通过熔断器来修改服务,而是使用诸如 Envoy 之类的辅助工具来交付我们的应用序。该服务的所有出站流量都是通过 envoy 进行代理。Envoy 支持开箱即用的断路功能。以下是 Envoy 的断路配置示例:

circuit_breakers:
thresholds:

  • priority: DEFAULT
    max_connections: 1000
    max_requests: 1000
  • priority: HIGH
    max_connections: 2000
    max_requests: 2000

最初发布于:
https : //iyer.ai/notes/index.php/2020/06/11/circuit-breakers-in-microservices/

感谢 Nishant M Gandhi 的意见。

参考资源:

参考阅读:

  • 构建 Netflix 分布式追踪(tracing)体系
  • AIOps在美团的探索与实践——故障发现篇
  • 一个加班多新人多团队,我们的代码问题与重构
  • 6种常用的架构设计模式(上)
  • 专家说别用 if-else 编码方式,那代码怎么写

本文由高可用架构翻译,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。

高可用架构

改变互联网的构建方式

技术图片
高可用架构
改变互联网的构建方式

长按二维码 关注「高可用架构」公众号

3分钟简述熔断器使用方法

标签:pytho   参考   expec   water   责任   ref   调用   传递   联系   

原文地址:https://blog.51cto.com/14977574/2546027

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!