不可否认,在过去几年中,像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