微服务之熔断利器

微服务之熔断利器

首页休闲益智堆栈断路器3D更新时间:2024-04-29

不可否认,在过去几年中,像Docker和Kubernetes这样相关的容器技术,彻底改变了我们对软件开发和部署的认知。

尽管软件行业的快速迭代推动着开发人员采用最新技术,也要适时停下脚步思考,能够实现的这些技术到底有没有一些固定套路?

熔断作为微服务体系中采用比较广泛的一种技术,就是这些固定套路中的一种,下面我们将介绍熔断的两种不同实现的优缺点:Hystrix和Istio

微服务同步通信过程中核心问题

想象一个非常简单的微服务架构,包括:

1.后端服务

2.前端服务

让我们假设后端和前端通过同步HTTP调用进行通信。

客户端C1和C2调用前端来请求一些信息。由于前端没有所有必需的数据,因此它会调用后端来获取缺失的部分。

但由于网络通信,可能会发生很多事情:

1.前端和后端之间的网络故障

2. 由于存在错误,后端可能会宕机

3. 后端依赖的服务(例如数据库)可能宕机

根据墨菲定律(“任何可能出错的东西都会出错”),前端和后端之间的通信迟早会失败。

如果我们查看从前端到后端的单个请求的生命周期,并考虑后端因任何原因而关闭,在某些时候,前端在指定的超时时间内取消请求。

缩小到应用程序级别,多个客户端同时调用前端,每个请求都会透传到后端,如果前后端存在任何不稳定情况,都会导致前端请求堆积,直至前端应用挂掉。

在这种情况下唯一合理的解决方案是快速失败:应该让前端知道后端出现问题,并立即将错误返回给自己的客户端。

熔断方案

在电路领域中,断路器是设计用于保护电路的自动操作的电气开关。其基本功能是在检测到故障后中断电流。然后可以在故障解决后重置(手动或自动)以恢复正常操作。

这看起来非常类似于我们的问题:为了保护我们的前端过载请求,最好在后端检测到重复异常时立即中断前端和后端之间的通信。

在Michael Nygard已上市的书中,他使用了这个类比,并提出了应用于上述熔断问题的设计模式。它背后的流程非常简单:

如果呼叫失败,请将失败呼叫的数量增加1

如果失败的呼叫数超过某个阈值,请打开电路

如果电路处于打开状态,则立即返回错误或默认响应

如果电路开路且经过一段时间,则半开电路

如果电路半开,下一次呼叫失败,请再次打开

如果电路半开,下一次通话成功,请将其关闭

这可以在下图中总结:

熔断利器之一:lstio

Istio是服务网格,是微服务应用程序的可配置基础设施层。它使服务实例之间的通信变得灵活,可靠和快速,并提供服务发现,负载平衡,加密,身份验证和授权,对熔断的支持以及其他功能。

Istio的控制面板在形如Kubernetes,Mesos底层集群管理平台上提供了一个抽象层,并且需要以这种方式管理您的应用程序。

作为其核心,Istio包括了使用sidecar容器模式并位于应用程序实例前面的Envoy Proxy,以及管理它们的工具Pilot。这种代理策略有许多优点:

HTTP,gRPC,WebSocket和TCP流量的自动负载平衡。

通过丰富的路由规则,重试,故障转移和故障注入,对流量行为进行细粒度控制。

插件化的策略层和配置API,支持访问控制,速率限制和配额。

集群中所有流量的自动指标采集,日志和跟踪,包括集群入口和出口。

通过强大的基于身份的身份验证和授权,在集群中实现安全的服务到服务通信。

由于对后端的调用是通过Envoy代理,因此很容易检测到它们何时超时。然后代理可以拦截进一步的请求并立即返回,有效地快速失败。特别是,这使得熔断能够以黑盒方式操作。

熔断利器之一Istio:配置

正如我们所说,Istio在您选择的集群管理平台上构建,并且需要通过它来部署您的应用程序。 Kubernetes通过DestinationRule实现熔断模式,或者更具体地说,按照如下链路TrafficPolicy(以前称为circuitBreaker) - > OutlierDetection,根据以下模型:

参数如下:

与上述标称熔断相比,有两个主要偏差:

没有半开状态这样的事情。但是,熔断器保持打开的持续时间取决于被叫服务之前失败的次数。不断失效的服务将导致熔断器的打开持续时间越来越长。

在基本模式中,有一个叫做应用程序(后端)。在更现实的生产环境中,可能会在负载均衡器后面部署同一应用程序的多个实例。有些实例可能会失败,有些可能会失效,而且由于Istio也扮演了负载平衡器的角色,它能够跟踪失败的实例并将它们从负载平衡池中移除,直到达到:maxEjectionPercent中配置的不移除后端服务最高的百分比。

熔断器的Istio接近是黑盒子,它能够在后端服务出问题时,自动熔断。另一方面,它设置起来非常简单,并且不需要任何底层代码知识,并且可以事后进行配置。

熔断利器之一:Hystrix

Hystrix是一个最初由Netflix提供的开源Java库。它是一个延迟和容错库,旨在隔离对远程系统,服务和第三方库的依赖,停止级联故障,并在复杂的分布式系统中实现弹性,因为在这些系统中,故障是不可避免的。

Hystrix有许多功能,包括:

防止通过第三方客户端库访问导致的延迟和故障。

防止复杂分布式系统中的级联故障。

快速失败并迅速恢复。

在可能的情况下,后退并优雅地降级。

实现近实时监控,警报和操作控制。

当然,熔断是众多特性中一个。因为Hystrix是一个库,它以白盒方式实现它。

Resilience4J

Netflix最近宣布已停止开发Hystrix库,转而采用不太知名的Resilience4J项目。

即使客户端代码可能有点不同,Hystrix和Resilience4J之间的方法也是类似的。

Hystrix熔断示例

考虑电子商务Web应用程序的情况。该应用程序的体系结构由不同的微服务构成,每个服务都基于业务功能:

认证

类目浏览

购物车管理

定价和报价

等等。

显示类目项时,将查询定价/报价微服务的价格。如果它宕机,是否开启熔断,它都将不会发回任何价格,也无法订购任何东西。

从商业角度来看,任何停机时间不仅会对品牌的感知产生影响,还会降低销售额。尽管价格并不完全正确,但大多数销售策略仍倾向于出售。实现此销售策略的解决方案可以是在可用时缓存定价/报价服务返回的价格,并在服务停止时返回缓存价格。

Hystrix通过提供熔断后回调fallback方法,实现后端服务异常,在回调方法中进行业务处理

这是Hystrix模型的简化类图:

核心处理是在HystrixCommand方法run()和getFallback()中:

run()是实际代码,例如 从报价服务中获取价格

当熔断打开时,getFallabck()获得备用结果,例如 返回缓存价格

这可以使用Spring的RestTemplate转换为以下代码:

代码一些解释:

该Command包装产品的id,建模为UUID。

Spring的RestTemplate用于进行REST调用。 任何其他选择都可以。

共享JCache实例,用于在服务可用时存储定价。

Hystrix命令需要组密钥,以便在需要时将它们组合在一起。 这是Hystrix的另一个特性,超出了本文的范围。 有兴趣的读者可以阅读Hystrix wiki中的命令组。

执行对引用服务的调用。 如果失败,则启动Hystrix熔断流量。

如果调用成功,则将返回的引用缓存在JCache共享实例中。

熔断打开时调用getFallback()。 在这种情况下,从缓存中获取引用。

Hystrix wiki具有更高级的示例,例如 fallback本身就是一个需要执行的command。

Hystrix 和spring Cloud集成

虽然上面的代码有效,但每次引用时都需要创建一个Hystrix Commend对象。

Spring Cloud是一个构建在Spring Boot之上的库(它本身构建在Spring框架之上),它提供了与Spring的完美集成。 它允许在处理Hystrix Commend对象的实例化时,只注释所需的回退方法:

该方法应使用@HystrixCommand进行注释。 fallbackMethod元素引用了fallback方法。显然,这将通过反射来处理,并且不是类型安全的 - 毕竟这是一个字符串。

Spring Cloud Hystrix允许在方法调用时传递产品的id参数。与上面的简单Hystrix Command相比,这允许具有通用服务对象。 Hystrix Command的创建由Spring Cloud在运行时处理。

核心逻辑不会改变。

同样,缓存过程保持不变。

fallback方法是常规方法。它将使用与main方法完全相同的参数值进行调用,因此它必须具有相同的参数类型(以相同的顺序)。因为getQuoteFor()方法接受UUID,所以此方法也是如此。

Hystrix,无论是独立的还是由Spring Boot Cloud包装,都需要在代码级别处理熔断。因此,它需要提前计划,并且更改需要重新部署应用。但是,当出现问题时,可以实现非常精细的定制行为。

Istio vs Hystrix:熔断之战

如果事情有可能失败,或者在超时时失败,并且严重依赖网络的微服务,需要考虑熔断。熔断器模式是处理服务可用性不足的方法之一:它不是排队请求和阻塞调用者,而是快速失败并立即返回。

有两种方法可以实现熔断器,黑盒方式和白盒方式。 Istio作为代理管理工具,采用黑盒方式。它实现起来很简单,它不依赖于底层技术堆栈,它可以被配置为事后的想法。

另一方面,Hystrix库使用白盒方式。它允许拥有所有不同类型的fallback:

单个默认值

缓存

请求其他服务。

它还提供级联fallback。这些附加功能需要付出代价:它需要在仍处于开发阶段时做出fallback决策。

两种方法之间的最佳匹配可能取决于一个人自己的背景:在某些情况下,例如引用服务,带有fallback的白盒策略可能更适合,而对于其他情况,快速失败可能完全可以接受,例如集中式远程日志服务。

当然,没有什么能阻止你同时使用它们。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved